diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..c36d5e7 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Refer to https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file + +* @trpc-ecosystem/tRPC-Go diff --git a/.github/typosconfig.toml b/.github/typosconfig.toml new file mode 100644 index 0000000..059bb49 --- /dev/null +++ b/.github/typosconfig.toml @@ -0,0 +1,13 @@ +[default] +extend-ignore-identifiers-re = [ + "AttributeID.*Supress.*", +] + +[default.extend-identifiers] +AttributeIDSupressMenu = "AttributeIDSupressMenu" + +[default.extend-words] +WRONLY = "WRONLY" + +[files] +extend-exclude = ["install/submodules/*"] diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 0000000..46700dd --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,32 @@ +name: "CLA Assistant" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, synchronize, reopened] + +# explicitly configure permissions, in case your GITHUB_TOKEN workflow permissions are set to read-only in repository settings +permissions: + actions: write + contents: write + pull-requests: write + statuses: write + +jobs: + CLAAssistant: + runs-on: self-hosted + steps: + - name: "CLA Assistant" + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@v2.3.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_DATABASE_ACCESS_TOKEN }} + with: + remote-organization-name: trpc-group + remote-repository-name: cla-database + path-to-signatures: 'signatures/${{ github.event.repository.name }}-${{ github.repository_id }}/cla.json' + path-to-document: 'https://github.com/trpc-group/cla-database/blob/main/Tencent-Contributor-License-Agreement.md' + # branch should not be protected + branch: 'main' + allowlist: bot* diff --git a/.github/workflows/prc.yml b/.github/workflows/prc.yml new file mode 100644 index 0000000..b1efdcd --- /dev/null +++ b/.github/workflows/prc.yml @@ -0,0 +1,75 @@ +name: Pull Request Check +on: + pull_request: + workflow_dispatch: +permissions: + contents: read + pull-requests: read # Use with `only-new-issues` option. +jobs: + build: + name: build + runs-on: self-hosted + steps: + - uses: actions/checkout@v3 + # with: + # ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} + # submodules: 'recursive' + - name: Checkout submodules using a PAT + run: | + git config --file .gitmodules --get-regexp url | while read url; do + git config --file=.gitmodules $(echo "$url" | sed -E "s/git@github.com:|https:\/\/github.com\//https:\/\/${{ secrets.TRPC_PAT }}:${{ secrets.TRPC_PAT }}@github.com\//") + done + git submodule sync + git submodule update --init --recursive + - run: ls install/submodules/trpc-protocol + - uses: actions/setup-go@v4 + with: + go-version: 1.19 + - name: Build + run: go build -v ./... + - name: Set env + run: echo "$HOME/go/bin" >> $GITHUB_PATH + - name: Install protoc + run: PB_REL="https://github.com/protocolbuffers/protobuf/releases" && curl -LO $PB_REL/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip && unzip -o protoc-3.15.8-linux-x86_64.zip -d $HOME/.local && ~/.local/bin/protoc --version + - name: Install flatc + run: wget https://github.com/google/flatbuffers/releases/download/v23.5.26/Linux.flatc.binary.g++-10.zip && unzip Linux.flatc.binary.g++-10.zip && mv flatc ~/go/bin/ && ~/go/bin/flatc --version + - name: Install protoc-gen-go + run: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + - name: Install goimports + run: go install golang.org/x/tools/cmd/goimports@latest + - name: install mockgen + run: go install go.uber.org/mock/mockgen@latest + - run: echo $PATH + - run: export PATH=$HOME/.local/bin:$HOME/go/bin:$PATH && echo $PATH && go run ./trpc setup -f && ls -la /home/ubuntu/go/bin && file $HOME/go/bin/flatc && file $HOME/go/bin/protoc + - name: Test + run: export PATH=$HOME/.local/bin:$HOME/go/bin:$PATH && echo $PATH && go test -v -coverprofile=coverage.out ./... + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + files: coverage.out + flags: unittests + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + golangci: + name: lint + runs-on: self-hosted + steps: + - uses: actions/setup-go@v4 + with: + go-version: 1.19 + - uses: actions/checkout@v3 + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + only-new-issues: true + skip-cache: true + typos: + name: typos + runs-on: self-hosted + steps: + - uses: actions/checkout@v3 + - name: typos + uses: crate-ci/typos@master + with: + config: ./.github/typosconfig.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2873344 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# ignore tempfiles generated by IDE... +.DS_Store +.idea +.vscode +*.iml + +# ignore ./bin rather than install/asset_dart/bin/ +/bin + +# ignore generated files when run go test +testcase/create/generated +testcase/create/generated-non-protocol-type/ +docs/examples/**/bin +util/pb/testcase/*.go +util/pb/testcase/generated/ + +# ignore generated binaries when run go build +/trpc/trpc +/trpc/trpc.exe + +*.log diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d0ca37a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "install/submodules/trpc-protocol"] + path = install/submodules/trpc-protocol + url = git@github.com:trpc-group/trpc.git + branch = main diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100644 index 0000000..8d88ef7 --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,107 @@ +# Community Code of Conduct + +Welcome to our open source project! + +We are committed to creating a friendly, respectful, and inclusive community. + +To ensure a positive experience in our project, we have established the following code of conduct, which we require all participants to abide by, and provide a safe and inclusive environment for all community members. + +## Our Pledge + +As participants, contributors, and maintainers of our community, we pledge to: +- Treat everyone with openness, inclusivity, and collaboration; +- Respect individuals with different backgrounds and viewpoints, regardless of gender, sexual orientation, disability, race, ethnicity, religion, age, or any other factor; +- Focus on contributing and improving the project, rather than attacking or criticizing individuals; +- Build trust with community members and promote our project through constructive feedback; +- Provide a safe, supportive, and encouraging environment for community members to promote learning and personal growth. + +## Our standards + +Our community members should adhere to the following standards: +- Respect the opinions, viewpoints, and experiences of others; +- Avoid using insulting, discriminatory, or harmful language; +- Do not harass, intimidate, or threaten others; +- Do not publicly or privately disclose others' private information, such as contact information or addresses; +- Respect the privacy of others; +- Establish a safe, inclusive, and respectful environment for community members. + +## Our responsibility + +Project maintainers have a responsibility to create a friendly, respectful, and inclusive environment for our community members. + +They should: +- Clearly and publicly explain the community guidelines; +- Handle reports of guideline violations and resolve disputes appropriately; +- Protect the privacy and security of all community members; +- Maintain a fair, transparent, and responsible attitude. + +## Scope + +This code of conduct applies to all project spaces, including GitHub, mailing lists, forums, social media, gatherings, and conferences. + +Violations of the code of conduct will be dealt with, including but not limited to warnings, temporary or permanent bans, revocation of contribution rights, and revocation of project access rights. + +## Implementation guidelines + +If you encounter behavior that violates this code of conduct, you can: +- Communicate privately with the relevant person to try to resolve the issue; +- Report the violation to the project maintainers(maintainer mailing list), who will take necessary action based on the situation; +- If you are not satisfied with the way the maintainers handle the situation, you can seek help from higher-level organizations or institutions. + +Our community is a diverse, open, and inclusive community, and we welcome everyone's participation and contribution. + +We believe that only in a safe, respectful, and inclusive environment can we create the best project together. + +--- + +# 社区行为准则 + +欢迎来到我们的开源项目!我们致力于创建一个友好、尊重和包容的社区,我们希望所有人都能为此做出贡献。 + +为了确保在我们的项目中有一个积极的体验,我们制定了以下行为准则,我们要求所有参与者遵守这些准则,并向所有社区成员提供一个安全和包容的环境。 + +## 我们的承诺 + +作为我们社区的参与者、贡献者和维护者,我们承诺: +- 以开放、包容和合作的态度对待所有人; +- 尊重不同背景和观点的人,不论是性别、性取向、残疾、种族、民族、宗教、年龄或任何其他因素; +- 专注于对项目的贡献和改进,而不是对个人的攻击或抨击; +- 与社区成员建立互信关系,通过积极的反馈来推动我们的项目发展; +- 为社区成员提供一个安全、支持和鼓励的环境,以促进学习和个人成长。 + +## 我们的标准 + +我们的社区成员应该遵守以下标准: +- 尊重他人的意见、观点和经验; +- 避免使用侮辱性、歧视性或有损的语言; +- 不要骚扰、恐吓或威胁他人; +- 不要公开或私下发布他人的私人信息,例如联系方式或地址; +- 尊重他人的隐私权; +- 为社区成员建立安全、包容和尊重的环境。 + +## 我们的责任 + +项目维护者有责任为我们的社区成员创造一个友好、尊重和包容的环境。 + +他们应该: +- 明确和公开地说明社区准则; +- 处理准则违规行为的举报,通过适当的方式解决纠纷; +- 保护所有社区成员的隐私和安全; +- 保持公正、透明和负责任的态度。 + +## 管理范围 + +本行为准则适用于所有的项目空间,包括 GitHub、邮件列表、论坛、社交媒体、聚会和会议等。 + +违反准则的行为将受到处理,包括但不限于警告、暂时或永久禁言、撤销贡献权、撤销项目访问权等。 + +## 实施指南 + +如果你遇到了违反本准则的行为,你可以: +- 私下与相关人员沟通,以尝试解决问题; +- 向项目维护者报告违规行为,维护者会根据情况采取必要的行动; +- 如果你不满意维护者的处理方式,你可以向更高级别的机构或组织寻求帮助。 + +我们的社区是一个多样化、开放和包容的社区,我们欢迎所有人的参与和贡献。 + +我们相信,只有在一个安全、尊重和包容的环境中,我们才能共同创造出最优秀的项目。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..f702e8a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,126 @@ +# How to Contribute + +Thank you for your interest and support in tRPC! + +We welcome and appreciate any form of contribution, including but not limited to submitting issues, providing improvement suggestions, improving documentation, fixing bugs, and adding features. + +This document aims to provide you with a detailed contribution guide to help you better participate in the project. + +Please read this guide carefully before contributing and make sure to follow the rules here. + +We look forward to working with you to make this project better together! + +## Before submitting an issue + +Please make sure that you have reviewed the project's documentation, FAQ, and existing issues. + +This can avoid submitting known issues repeatedly and save your and the project maintainer's time. + +When you decide to submit an issue, please follow these rules: +- Select appropriate labels for the issue. This helps us to quickly locate the problem and solve it as soon as possible. +- Ensure that the issue title is concise and accurately summarizes the problem. Avoid using vague words such as "problem" or "error". + +In the issue description, please provide a detailed description of the problem you encountered. + +This includes but is not limited to the following: +- Problem description: briefly describe the symptoms and impact of the problem. +- Reproduction steps: describe in detail how to reproduce the problem, so that we can locate and solve the problem more quickly. +- Environment information: relevant information including operating system, browser, project version, etc. +- Error log: if there are relevant error logs, please provide them. +- Expected results: describe what the correct result should be. +- Screenshots or screen recordings: if possible, provide screenshots or screen recordings of the problem. + +Please be polite and friendly. + +We attach great importance to the environment of the project and hope that everyone can grow together in a friendly and inclusive environment. + +## Rules for submitting PRs + +We welcome you to submit code for the project. + +Before submitting a PR, please make sure that you have read this contribution guide. + +Here are some suggestions and rules regarding submitting PRs. + +Please read them carefully before submitting: +- Ensure that your code conforms to the project's code specifications. This includes but is not limited to code style, comment specifications, etc. This helps us to maintain the cleanliness and consistency of the project. +- Before submitting a PR, please make sure that you have tested your code locally. Ensure that the code has no obvious errors and can run normally. +- Please select appropriate labels for your PR. This helps us to process your PR more quickly. +- Ensure that your PR title is concise and accurately summarizes your changes. Avoid using vague words such as "update" or "modify". +- In the PR description, please provide a detailed description of your changes. This includes but is not limited to the following: + - Reason for modification: briefly explain why this modification is necessary. + - Modification content: describe in detail what you have modified and how you have implemented it. + - Scope of impact: describe the functions or modules that may be affected by the modification. + - Testing: describe the testing you have done locally and the results. +- If your PR resolves a certain issue, please associate the corresponding issue in the PR description. For example: Fixes #123. + +## Communication and Consultation + +We welcome you to participate in the project's communication and consultation. + +You can interact with us through the following channels: +- Submit your questions or suggestions in the project's discussions. +- Join our technical communication group. + +--- + +# 如何作出贡献 + +首先,感谢您对本开源项目的关注和支持! + +我们非常欢迎和感谢任何形式的贡献,包括但不限于提交问题、提出改进意见、完善文档、修复缺陷以及新增功能。 + +本文档旨在为您提供一份详尽的贡献指南,以便您更好地参与到项目中。 + +请在参与贡献之前仔细阅读本指南,并确保遵循其中的规则和建议。 + +我们期待与您一起打造一个更加完善的开源项目! + +## 提交 issue 的规则 + +在提交 issue 之前,请先确保您已经查看了项目的文档、常见问题解答以及已有的 issue。 + +这样可以避免重复提交已知问题,节省您和项目维护者的时间。 + +当您确定需要提交一个 issue 时,请遵循以下规则: +- 为 issue 选择合适的标签。这有助于我们更快地找到问题所在,以便尽快解决。 +- 请确保您的 issue 标题简洁明了,能够准确概括问题所在。避免使用模糊的词语,如“问题”、“错误”等。 + +在 issue 描述中,请详细说明您遇到的问题。 + +包括但不限于以下内容: +- 问题描述:简要说明问题的现象和影响。 +- 复现步骤:详细描述如何复现问题,让我们能够更快地定位和解决问题。 +- 环境信息:包括操作系统、浏览器、项目版本等相关信息。 +- 错误日志:如果有相关错误日志,请一并提供。 +- 期望结果:描述您期望的正确结果是什么。 +- 截图或录屏:如果可能,请提供问题现象的截图或录屏。 + +请保持礼貌和友好。我们非常重视项目的氛围,希望每个人都能够在友好、包容的环境中共同成长。 + +## 提交 PR 的规则 + +我们非常欢迎您为项目提交代码。 + +在提交 PR 之前,请确保您已经阅读了项目的文档以及本贡献指南。 + +以下是关于提交 PR 的一些建议和规则,请在提交前仔细阅读: + +- 请确保您的代码符合项目的代码规范。这包括但不限于代码风格、注释规范等。这有助于我们保持项目的整洁和一致性。 +- 在提交 PR 之前,请确保您已经在本地测试过您的代码。确保代码没有明显的错误,并能够正常运行。 +- 请为您的 PR 选择合适的标签。这有助于我们更快地处理您的 PR。 +- 请确保您的 PR 标题简洁明了,能够准确概括您的修改。避免使用模糊的词语,如“更新”、“修改”等。 +- 在 PR 描述中,请详细说明您的修改内容。包括但不限于以下内容: + - 修改原因:简要说明为什么要进行这次修改。 + - 修改内容:详细描述您修改了哪些内容,以及修改的具体实现。 + - 影响范围:说明修改可能影响到的功能或模块。 + - 测试情况:描述您在本地测试的情况,以及测试结果。 +- 如果您的 PR 解决了某个 issue,请在 PR 描述中关联对应的 issue。例如:Fixes #123。 + +## 技术交流与问题咨询 + +我们非常欢迎您参与到项目的技术交流和问题咨询中来。 + +您可以通过以下途径与我们互动: +- 在项目的 discussions 中提交您的问题或建议 +- 加入我们的技术交流群 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md new file mode 100644 index 0000000..56e7e4c --- /dev/null +++ b/CONTRIBUTORS.md @@ -0,0 +1,75 @@ +# Contributor Guidelines + +Thank you for your interest and support for tRPC! + +This document outlines the roles and responsibilities of contributors in the project, as well as the process for becoming a Contributor and losing Maintainer status. We hope that this document will help every contributor understand the growth path and make a greater contribution to the project's development. + +## Contributor Roles and Responsibilities + +we have two main contributor roles: Contributor and Maintainer. + +Here is a brief introduction to these two roles: +1. Contributor: A contributor to the project who can contribute code, documentation, testing, and other resources. Contributors provide valuable resources to the project, helping it to continuously improve and develop. +2. Maintainer: A maintainer of the project who is responsible for the day-to-day maintenance of the project, including reviewing and merging PRs, handling issues, and releasing versions. Maintainers are key members of the project and have a significant impact on the project's development direction and decision-making. + +## How to become a Maintainer + +We welcome every contributor to contribute to the project's development and encourage contributors to upgrade to the role of Maintainer. + +The following are the conditions for upgrading from Contributor to Maintainer: +1. Continuous contribution: Contributors need to contribute to the project continuously for a period of time (e.g., 3 months). This demonstrates the contributor's attention and enthusiasm for the project. +2. Quality assurance: The code or documentation submitted by contributors needs to maintain a high level of quality, meet the project's specifications, and have a positive impact on the project. +3. Active participation: Contributors need to actively participate in project discussions and decision-making, providing constructive opinions and suggestions for the project's development. +4. Team collaboration: Contributors need to have good teamwork skills, communicate friendly with other contributors and maintainers, and work together to solve problems. +5. Responsibility: Contributors need to have a certain sense of responsibility and be willing to undertake some of the project maintenance work, including reviewing PRs and handling issues. When a contributor meets the above conditions, existing maintainers will evaluate them. + +If they meet the requirements of Maintainer, they will be invited to become a new Maintainer. + +## Losing Maintainers status + +Maintainer have important responsibilities in the project, and we hope that every Maintainer can maintain their attention and enthusiasm for the project. + +However, we also understand that everyone's time and energy are limited, so when Maintainers cannot continue to fulfill their responsibilities, they will be downgraded to the role of Contributor: +1. Long-term inactivity: If a Maintainer has not participated in project maintenance work, including reviewing PRs and handling issues, for a period of time (e.g., 3 months), they will be considered inactive. +2. Quality issues: If a Maintainer's work in the project has serious quality issues that affect the project's development, they will be considered not meeting the requirements of Maintainer. +3. Team collaboration issues: If a Maintainer has serious communication or teamwork issues with other contributors and maintainers, such as disrespecting others' opinions, frequent conflicts, or refusing to collaborate, which affects the project's normal operation and atmosphere, they will be considered not meeting the requirements of Maintainer. +4. Violation of rules: If a Maintainer violates the project's rules or code of conduct, including but not limited to leaking sensitive information or abusing privileges, they will be considered not meeting the requirements of Maintainer. +5. Voluntary application: If a Maintainer cannot continue to fulfill their responsibilities due to personal reasons, they can voluntarily apply to be downgraded to the role of Contributor. + +--- + +# 贡献者管理说明文档 + +感谢您对本开源项目的关注和支持!本文档将阐述贡献者在项目中的角色、职责以及如何从 Contributor 升级为 Maintainer,以及 Maintainer 降级为 Contributor 的规则。我们希望通过这份文档,让每位贡献者都能清楚地了解自己的成长路径,并为项目的发展做出更大的贡献。 + +## 贡献者角色及职责 + +在本开源项目中,我们主要设有两个贡献者角色:Contributor 和 Maintainer。 + +以下是对这两个角色的简要介绍: +1. Contributor:项目的贡献者,可以是代码贡献者、文档贡献者、测试贡献者等。Contributor 为项目提供了宝贵的资源,帮助项目不断完善和发展。 +2. Maintainer:项目的维护者,负责项目的日常维护工作,包括审查和合并 PR、处理 Issue、发布版本等。Maintainer 是项目的核心成员,对项目的发展方向和决策具有重要的影响力。 + +## Contributor 升级为 Maintainer + +我们非常欢迎每位 Contributor 为项目的发展做出贡献,并鼓励 Contributor 向 Maintainer 的角色发展。 + +以下是从 Contributor 升级为 Maintainer 的条件: +1. 持续贡献:Contributor 需要在一段时间内(例如 3 个月)持续为项目贡献代码、文档或其他资源。这表明 Contributor 对项目的关注度和热情。 +2. 质量保证:Contributor 提交的代码或文档等资源需要保持较高的质量,符合项目的规范要求,并对项目产生积极的影响。 +3. 积极参与:Contributor 需要积极参与到项目的讨论和决策中来,为项目的发展提供建设性的意见和建议。 +4. 团队协作:Contributor 需要具备良好的团队协作精神,能够与其他贡献者和 Maintainer 友好沟通,共同解决问题。 +5. 责任担当:Contributor 需要具备一定的责任心,愿意承担项目维护的部分工作,包括审查 PR、处理 Issue 等。 + +当 Contributor 满足以上条件时,现有的 Maintainer 将会对其进行评估,如果达到 Maintainer 的要求,将会邀请其成为新的 Maintainer。 + +## Maintainer 降级为 Contributor + +Maintainer 在项目中承担了重要的职责,我们希望每位 Maintainer 都能够保持对项目的关注和热情。 + +然而,我们也理解每个人的时间和精力是有限的,因此,当 Maintainer 无法继续履行职责时,将会降级为 Contributor: +1. 长时间不活跃:如果 Maintainer 在一段时间内(例如 3 个月)没有参与项目的维护工作,包括审查 PR、处理 Issue 等,将被视为不活跃。 +2. 质量问题:如果 Maintainer 在项目中的工作出现严重的质量问题,导致项目的发展受到影响,将被视为不符合 Maintainer 的要求。 +3. 团队协作问题:如果 Maintainer 在与其他贡献者和 Maintainer 的协作过程中出现严重的沟通问题或团队协作问题,如不尊重他人意见、频繁产生冲突、拒绝协作等,影响到项目的正常运作和氛围,将被视为不符合 Maintainer 的要求。 +4. 违反规定:如果 Maintainer 违反了项目的规定或行为准则,包括但不限于泄露敏感信息、滥用权限等,将被视为不符合 Maintainer 的要求。 +5. 主动申请:如果 Maintainer 由于个人原因无法继续履行职责,可以主动申请降级为 Contributor。 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8b09216 --- /dev/null +++ b/LICENSE @@ -0,0 +1,227 @@ +Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved. + +trpc-cmdline is licensed under the Apache License Version 2.0 except for the third-party components listed below. + +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + + + +Other dependencies and licenses: + + +Open Source Software Licensed under the MIT License: +-------------------------------------------------------------------- +1. gomonkey +Copyright (c) 2018 Zhang Xiaolong + +2. strcase +Copyright (c) 2015 Ian Coleman +Copyright (c) 2018 Ma_124, + +3. viper +Copyright (c) 2014 Steve Francia + +4. testify +Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. + +5. multierr +Copyright (c) 2017 Uber Technologies, Inc. + + +Terms of the MIT License: +-------------------------------------------------------------------- +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +Open Source Software Licensed under the Apache License Version 2.0: +-------------------------------------------------------------------- +1. go-billy +Copyright (c) go-billy original author and authors +Source code of this software can be obtained from: github.com/go-git/go-billy + +2. go-git +Copyright (c) go-git original author and authors +Source code of this software can be obtained from: github.com/go-git/go-git + +3. mock +Copyright (c) mock original author and authors +Source code of this software can be obtained from: github.com/golang/mock + +4. protoreflect +Copyright (c) protoreflect original author and authors +Source code of this software can be obtained from: github.com/jhump/protoreflect + +5. cobra +Copyright (c) cobra original author and authors +Source code of this software can be obtained from: github.com/spf13/cobra + +6. yaml.v2 +Copyright 2011-2016 Canonical Ltd. + +Source code of this software can be obtained from: gopkg.in/yaml.v2 + + +Terms of the Apache License Version 2.0: +-------------------------------------------------------------------- +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + + + +Open Source Software Licensed under the BSD 3-Clause License: +-------------------------------------------------------------------- +1. promptui +Copyright (c) 2017, Arigato Machine Inc. All rights reserved. + +2. pflag +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +3. protobuf +Copyright (c) 2018 The Go Authors. All rights reserved. + + +Terms of the BSD 3-Clause License: +-------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +Open Source Software Licensed under the BSD 2-Clause License: +-------------------------------------------------------------------- +1. errors +Copyright (c) 2015, Dave Cheney +All rights reserved. + + +Terms of the BSD 2-Clause License: +-------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ae4777d --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +VERSION := $(shell cat install/VERSION) +PHONY: fmt bindata_release release submodules image + + +fmt: + @gofmt -s -w . + @goimports -w -local trpc.group . + +# If you want to construct bindata and then restore to the initial +# status of submodules, use `make release` +# +# If you only want to construct bindata, use `make bindata_release`, +# but be cautious that the files of submodules has been modified, if +# you want to create a merge request, you need to run `make submodules` +# to restore the status. +release: bindata_release submodules + +bindata_release: + # -git submodule update --init --recursive + # -rm -rf install/submodules/* && git submodule update --remote + # -cd install/submodules/trpc-protocol && (ls | grep -v "trpc" | xargs rm -rf) && find . -type f ! -name "*.proto" -exec rm -rf '{}' \; && cd - + @cat config/version.go | grep -oE "(v[0-9]+.[0-9]+.[0-9]+)" | tr -d '\n' > install/VERSION + @go get -u trpc.group/trpc-go/trpc-cmdline/bindata + @# in case "go get -u" doesn't work in higher version of Go. + @go install trpc.group/trpc-go/trpc-cmdline/bindata + @bindata -input=install -output=gobin/assets.go -gopkg=gobin + # The dependency on strcase should be forced to v0.2.0 for compatibility. + @go get -u github.com/iancoleman/strcase@v0.2.0 + @go mod tidy + +submodules: + # -rm -rf install/submodules/* && git submodule update --remote + +image: + @mkdir -p bin + @GOOS=linux go build -o bin/ trpc/trpc.go + @docker build -t trpc-cmdline:${VERSION} . diff --git a/README.md b/README.md new file mode 100644 index 0000000..56a45d6 --- /dev/null +++ b/README.md @@ -0,0 +1,194 @@ +# trpc-cmdline + +[![Go Reference](https://pkg.go.dev/badge/github.com/trpc.group/trpc-cmdline.svg)](https://pkg.go.dev/github.com/trpc.group/trpc-cmdline) +[![Go Report Card](https://goreportcard.com/badge/github.com/trpc.group/trpc-go/trpc-cmdline)](https://goreportcard.com/report/github.com/trpc.group/trpc-go/trpc-cmdline) +[![LICENSE](https://img.shields.io/github/license/trpc.group/trpc-cmdline.svg?style=flat-square)](https://github.com/trpc.group/trpc-cmdline/blob/main/LICENSE) +[![Releases](https://img.shields.io/github/release/trpc.group/trpc-cmdline.svg?style=flat-square)](https://github.com/trpc.group/trpc-cmdline/releases) +[![Docs](https://img.shields.io/badge/docs-latest-green)](http://test.trpc.group.woa.com/docs/) +[![Tests](https://github.com/trpc.group/trpc-cmdline/actions/workflows/prc.yaml/badge.svg)](https://github.com/trpc.group/trpc-cmdline/actions/workflows/prc.yaml) +[![Coverage](https://codecov.io/gh/trpc.group/trpc-cmdline/branch/main/graph/badge.svg)](https://app.codecov.io/gh/trpc.group/trpc-cmdline/tree/main) + +trpc-cmdline is the command line tool for [trpc-go](https://github.com/trpc-group/trpc-go). + +It supports the latest three major releases of [Go](https://go.dev/doc/devel/release). + +## Installation + +### Install trpc-cmdline + +#### Install using go command + +```bash +go install trpc.group/trpc-go/trpc-cmdline/trpc@latest +``` + +#### Install from release + +
Click to show the bash script
+$ TAG="v0.0.1" # Choose tag.
+$ OS=linux # Choose from "linux", "darwin" or "windows".
+$ wget -O trpc https://github.com/trpc-group/trpc-cmdline/releases/download/${TAG}/trpc_${OS}
+$ mkdir -p ~/go/bin && chmod +x trpc && mv trpc ~/go/bin
+$ export PATH=~/go/bin:$PATH # Add this to your `~/.bashrc`.
+
+ +### Dependencies + +Install Go: [https://go.dev/doc/install](https://go.dev/doc/install) + +Install other dependencies by using one of the following methods. + +#### Using trpc setup + +After installation of trpc-cmdline, simply running `trpc setup` will automatically install all the dependencies. + +#### Install separately + +
Install protoc
+$ # Reference: https://grpc.io/docs/protoc-installation/
+$ PB_REL="https://github.com/protocolbuffers/protobuf/releases"
+$ curl -LO $PB_REL/download/v3.15.8/protoc-3.15.8-linux-x86_64.zip
+$ unzip -o protoc-3.15.8-linux-x86_64.zip -d $HOME/.local
+$ export PATH=~/.local/bin:$PATH # Add this to your `~/.bashrc`.
+$ protoc --version
+libprotoc 3.15.8
+
+ +
Install flatc
+$ # Reference: https://github.com/google/flatbuffers/releases
+$ wget https://github.com/google/flatbuffers/releases/download/v23.5.26/Linux.flatc.binary.g++-10.zip
+$ unzip -o Linux.flatc.binary.g++-10.zip -d $HOME/.bin
+$ export PATH=~/.bin:$PATH # Add this to your `~/.bashrc`.
+$ flatc --version
+flatc version 23.5.26
+
+ +
Install protoc-gen-go
+$ # Reference: https://grpc.io/docs/languages/go/quickstart/
+$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+
+ +
Install goimports
+$ go install golang.org/x/tools/cmd/goimports@latest
+
+ +
Install mockgen
+$ # Reference: https://github.com/uber-go/mock
+$ go install go.uber.org/mock/mockgen@latest
+
+ + +## Quick Start + +### Generation of Full Project + +* Copy and paste the following to `helloworld.proto`, you can get it from [./docs/helloworld/helloworld.proto](./docs/helloworld/helloworld.proto): + +```protobuf +syntax = "proto3"; +package helloworld; + +option go_package = "github.com/some-repo/examples/helloworld"; + +// HelloRequest is hello request. +message HelloRequest { + string msg = 1; +} + +// HelloResponse is hello response. +message HelloResponse { + string msg = 1; +} + +// HelloWorldService handles hello request and echo message. +service HelloWorldService { + // Hello says hello. + rpc Hello(HelloRequest) returns(HelloResponse); +} +``` + +* Using trpc-cmdline to generate a full project: +```go +$ trpc create -p helloworld.proto -o out +``` + +Note: `-p` specifies proto file, `-o` specifies the output directory, +for more information please run `trpc -h` and `trpc create -h` + +* Enter the output directory and start the server: +```bash +$ cd out +$ go run . +... +... trpc service:helloworld.HelloWorldService launch success, tcp:127.0.0.1:8000, serving ... +... +``` + +* Open the output directory in another terminal and start the client: +```bash +$ go run cmd/client/main.go +... simple rpc receive: +``` + +Note: Since the implementation of server service is an empty operation and the client sends empty data, therefore the log shows that the simple rpc receives an empty string. + +* Now you may try to modify the service implementation located in `hello_world_service.go` and the client implementation located in `cmd/client/main.go` to create an echo server. You can refer to [https://github.com/trpc-group/trpc-go/tree/main/examples/helloworld](https://github.com/trpc-group/trpc-go/tree/main/examples/helloworld) for inspiration. + +* The generated files are explained below: + +```bash +$ tree +. +|-- cmd +| `-- client +| `-- main.go # Generated client code. +|-- go.mod +|-- go.sum +|-- hello_world_service.go # Generated server service implementation. +|-- hello_world_service_test.go +|-- main.go # Server entrypoint. +|-- stub # Stub code. +| `-- github.com +| `-- some-repo +| `-- examples +| `-- helloworld +| |-- go.mod +| |-- helloworld.pb.go +| |-- helloworld.proto +| |-- helloworld.trpc.go +| `-- helloworld_mock.go +`-- trpc_go.yaml # Configuration file for trpc-go. +``` + +### Generation of RPC Stub + +* Simply add `--rpconly` flag to generate rpc stub instead of a full project: +```go +$ trpc create -p helloworld.proto -o out --rpconly +$ tree out +out +|-- go.mod +|-- go.sum +|-- helloworld.pb.go +|-- helloworld.trpc.go +`-- helloworld_mock.go +``` + +### Frequently Used Flags + +The following lists some frequently used flags. + +* `-f`: Force overwrite the existing code. +* `-d some-dir`: Search paths for pb files (including dependent pb files), can be specified multiple times. +* `--mock=false`: Disable generation of mock stub code. +* `--nogomod=true`: Do not generate go.mod file in the stub code, only effective when --rpconly=true, defaults to false. + +For additional flags please run `trpc -h` and `trpc [subcmd] -h`. + +### Functionalities + +Please check [Documentation](./docs/) + +## Contributing + +This project is open-source and accepts contributions. See the [contribution guide](CONTRIBUTING.md) for more information. diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..1d393a2 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,2 @@ +# trpc-cmdline + diff --git a/bindata/README.md b/bindata/README.md new file mode 100644 index 0000000..ee77b80 --- /dev/null +++ b/bindata/README.md @@ -0,0 +1,26 @@ +Moved from: https://trpc.group/gitcode/bindata + +# Introduction + +`bindata` is used for converting file or directory into a go file, whose package name can be specified. + +The original file data is stored in a exported variable, so it can be referenced in your code. + +# Installation + +``` +go get -u trpc.group/trpc-go/trpc-cmdline/bindata +``` +# Help + +```bash +$ bindata -h + +Usage of bindata: + -gopkg string + write transformed data to *.go, whose package is $package (default "gobin") + -input string + read data from input, which could be a regular file or directory + -output string + write transformed data to named *.go, which could be linked with binary +``` diff --git a/bindata/bindata.go b/bindata/bindata.go new file mode 100644 index 0000000..4de03ab --- /dev/null +++ b/bindata/bindata.go @@ -0,0 +1,95 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "os" + "path/filepath" + "text/template" + + "github.com/iancoleman/strcase" + + "trpc.group/trpc-go/trpc-cmdline/bindata/compress" +) + +var ( + input = flag.String("input", "", "read data from input, which could be a regular file or directory") + output = flag.String("output", "", "write transformed data to named *.go, which could be linked with binary") + gopkg = flag.String("gopkg", "gobin", "write transformed data to *.go, whose package is $package") +) + +var tpl = `package {{.GoPackage}} +var {{.Variable}} = []uint8{ +{{ range $idx, $val := .Data }}{{$val}},{{ end }} +}` + +func main() { + flag.Parse() + + // Validate input and output parameters. + if len(*input) == 0 || len(*gopkg) == 0 { + fmt.Println("invalid argument: invalid input") + os.Exit(1) + } + + // Read input content. + buf, err := readFromInputSource(*input) + if err != nil { + fmt.Printf("read data error: %v\n", err) + os.Exit(1) + } + + // Convert the content to a .go file and write it out. + inputBaseName := filepath.Base(*input) + if len(*output) == 0 { + *output = fmt.Sprintf("%s_bindata.go", inputBaseName) + } + + outputDir, outputBaseName := filepath.Split(*output) + tplInstance, err := template.New(outputBaseName).Parse(tpl) + if err != nil { + fmt.Printf("parse template error: %v\n", err) + os.Exit(1) + } + _ = os.MkdirAll(outputDir, 0777) + + fout, err := os.OpenFile(*output, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) + if err != nil { + fmt.Printf("open input error: %v", err) + os.Exit(1) + } + + err = tplInstance.Execute(fout, &struct { + GoPackage string + Variable string + Data []uint8 + }{ + GoPackage: *gopkg, + Variable: strcase.ToCamel(outputBaseName), + Data: buf, + }) + if err != nil { + panic(fmt.Errorf("template execute error: %v", err)) + } + + fmt.Printf("ok, filedata stored to %s\n", *output) +} + +// readFromInputSource reads content from an input source, +// which can be a file or a directory. +// The content will be gzipped then being returned. +func readFromInputSource(inputSource string) (data []byte, err error) { + _, err = os.Lstat(inputSource) + if err != nil { + return nil, err + } + + buf := bytes.Buffer{} + err = compress.Tar(inputSource, &buf) + if err != nil { + return nil, err + } + + return buf.Bytes(), nil +} diff --git a/bindata/bindata_test.go b/bindata/bindata_test.go new file mode 100644 index 0000000..0656954 --- /dev/null +++ b/bindata/bindata_test.go @@ -0,0 +1,33 @@ +package main + +import ( + "errors" + "os" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" +) + +func Test_readFromInputSource(t *testing.T) { + t.Run("case invalid input", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(os.Lstat, func(name string) (os.FileInfo, error) { + return nil, errors.New("fake error") + }) + defer p.Reset() + data, err := readFromInputSource("") + require.NotNil(t, err) + require.Nil(t, data) + }) + + t.Run("case success", func(t *testing.T) { + dir, err := os.Getwd() + if err != nil { + panic(err) + } + + _, err = readFromInputSource(dir) + require.Nil(t, err) + }) +} diff --git a/bindata/compress/tar.go b/bindata/compress/tar.go new file mode 100644 index 0000000..15bee7a --- /dev/null +++ b/bindata/compress/tar.go @@ -0,0 +1,138 @@ +package compress + +import ( + "archive/tar" + "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +// Tar takes a source and variable writers and walks 'source' writing each file +// found to the compress writer; the purpose for accepting multiple writers is to allow +// for multiple outputs (for example a file, or md5 hash) +func Tar(src string, writers ...io.Writer) error { + // ensure the src actually exists before trying to compress it + if _, err := os.Stat(src); err != nil { + return fmt.Errorf("Unable to compress files - %v", err.Error()) + } + + mw := io.MultiWriter(writers...) + + gzw := gzip.NewWriter(mw) + defer gzw.Close() + + tw := tar.NewWriter(gzw) + defer tw.Close() + + // walk path + return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { + // return on any error + if err != nil { + return err + } + + // return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) + //for this suggested update) + if !fi.Mode().IsRegular() { + return nil + } + + // create a new dir/file header + header, err := tar.FileInfoHeader(fi, fi.Name()) + if err != nil { + return err + } + + // update the name to correctly reflect the desired destination when untaring + header.Name = strings.TrimPrefix(strings.Replace(file, src, "", -1), string(filepath.Separator)) + + // write the header + if err := tw.WriteHeader(header); err != nil { + return err + } + + // open files for taring + f, err := os.Open(file) + if err != nil { + return err + } + + // copy file data into compress writer + if _, err := io.Copy(tw, f); err != nil { + return err + } + + // manually close here after each file operation; deferring would cause each file close + // to wait until all operations have completed. + f.Close() + + return nil + }) +} + +// Untar takes a destination path and a reader; a compress reader loops over the tarfile +// creating the file structure at 'dst' along the way, and writing any files +func Untar(dst string, r io.Reader) error { + gzr, err := gzip.NewReader(r) + if err != nil { + return err + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + + for { + header, err := tr.Next() + switch { + case err == io.EOF: + // if no more files are found return + return nil + case err != nil: + // return any other error + return err + case header == nil: + // if the header is nil, just skip it (not sure how this happens) + continue + } + + // the target location where the dir/file should be created + target := filepath.Join(dst, header.Name) + + // the following switch could also be done using fi.Mode(), not sure if there + // a benefit of using one vs. the other. + // fi := header.FileInfo() + + // check the file type + switch header.Typeflag { + case tar.TypeDir: + // if its a dir and it doesn't exist create it + if _, err := os.Stat(target); err != nil { + if err := os.MkdirAll(target, 0755); err != nil { + return err + } + } + case tar.TypeReg: + // if it's a file create it + dir, _ := filepath.Split(target) + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) + if err != nil { + return err + } + + // copy over contents + if _, err := io.Copy(f, tr); err != nil { + return err + } + + // manually close here after each file operation; deferring would cause each file close + // to wait until all operations have completed. + f.Close() + } + } +} diff --git a/bindata/compress/tar_test.go b/bindata/compress/tar_test.go new file mode 100644 index 0000000..6f84c06 --- /dev/null +++ b/bindata/compress/tar_test.go @@ -0,0 +1,82 @@ +package compress + +import ( + "bytes" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestTar(t *testing.T) { + // setup + tmp := os.TempDir() + dir := filepath.Join(tmp, "bindata") + err := os.MkdirAll(dir, os.ModePerm) + if err != nil { + panic(err) + } + fp := filepath.Join(dir, "test.txt") + txt := []byte("helloworld") + err = os.WriteFile(fp, txt, 0666) + if err != nil { + panic(err) + } + + // tar + buf := bytes.Buffer{} + err = Tar(fp, &buf) + require.Nil(t, err) + require.NotZero(t, buf.Len()) + + // untar + reader := bytes.NewReader(buf.Bytes()) + dst := filepath.Join(dir, "test2.txt") + err = Untar(dst, reader) + require.Nil(t, err) + + dat, err := os.ReadFile(dst) + require.Nil(t, err) + require.Equal(t, txt, dat) + + os.RemoveAll(dir) +} + +func TestTar_Install(t *testing.T) { + wd, err := os.Getwd() + if err != nil { + panic(err) + } + src := wd + + // tar + buf := bytes.Buffer{} + err = Tar(src, &buf) + require.Nil(t, err) + require.NotZero(t, buf.Len()) + + // untar + tmp := os.TempDir() + dst := filepath.Join(tmp, "bindata") + defer os.RemoveAll(dst) + + err = Untar(dst, &buf) + require.Nil(t, err) + + // compare file list + srcFileSet := map[string]struct{}{} + filepath.Walk(src, func(path string, info os.FileInfo, err error) error { + path = strings.TrimPrefix(path, src) + srcFileSet[path] = struct{}{} + return nil + }) + dstFileSet := map[string]struct{}{} + filepath.Walk(dst, func(path string, info os.FileInfo, err error) error { + path = strings.TrimPrefix(path, dst) + dstFileSet[path] = struct{}{} + return nil + }) + require.Equal(t, srcFileSet, dstFileSet) +} diff --git a/cmd/apidocs/apidocs.go b/cmd/apidocs/apidocs.go new file mode 100644 index 0000000..596741b --- /dev/null +++ b/cmd/apidocs/apidocs.go @@ -0,0 +1,156 @@ +// Package apidocs provides apidocs command. +package apidocs + +import ( + "errors" + "fmt" + "path/filepath" + + "github.com/spf13/cobra" + "github.com/spf13/pflag" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/openapi" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/swagger" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" + "trpc.group/trpc-go/trpc-cmdline/util/paths" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +// CMD returns apidocs command. +func CMD() *cobra.Command { + apidocsCmd := &cobra.Command{ + Use: "apidocs", + Short: "Generate apidocs", + Long: `Generate apidocs, supporting swagger and openapi. +When generating swagger documentation, the summary information of rpc methods +includes the leading comments of the rpc method in the pb file. +The field information of input and output also includes the leading and trailing comments of the field. + `, + RunE: runAPIDocs, + } + + // Flags related to swagger. + apidocsCmd.Flags().Bool("swagger", true, "Generate swagger apidocs") + apidocsCmd.Flags().Bool("swagger-json-param", false, "Generate swagger apidocs using json body") + apidocsCmd.Flags().String("swagger-out", "apidocs.swagger.json", "Output path for swagger apidocs") + + // Flags related to openapi. + apidocsCmd.Flags().Bool("openapi", false, "Generate openapi apidocs") + apidocsCmd.Flags().String("openapi-out", "apidocs.openapi.json", "Output path for openapi apidocs") + + // Proto files and search paths. + apidocsCmd.Flags().StringP("protofile", "p", "", "Specify the pb file for the service") + apidocsCmd.Flags().StringArrayP("protodir", "d", + []string{"."}, "Search paths for pb files (including dependency pb files), can be specified multiple times") + + // Flag for alias. + apidocsCmd.Flags().Bool("alias", false, "Use alias mode for rpcname") + + // The rules of documents order. + apidocsCmd.Flags().Bool("order-by-pbname", false, + "Use the order defined in the PB for api documentation, defaults to alphabetical order") + return apidocsCmd +} + +// runAPIDocs generates API documents. +func runAPIDocs(cmd *cobra.Command, _ []string) error { + if _, err := config.Init(); err != nil { + return fmt.Errorf("init config err: %w", err) + } + // Check the command line arguments. + option, err := loadAPIDocsOptions(cmd.Flags()) + if err != nil { + return fmt.Errorf("error checking command options: %w", err) + } + // Parse pb. + fileDescriptor, err := parser.Parse( + option.Protofile, + option.Protodirs, + option.IDLType, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + return fmt.Errorf("error parsing pb file %s: %w", option.Protofile, err) + } + // Dump fd for debugging. + fileDescriptor.Dump() + return genAPIDocs(fileDescriptor, option) +} + +func genAPIDocs(fileDescriptor *descriptor.FileDescriptor, option *params.Option) error { + if option.SwaggerOn { + if err := swagger.GenSwagger(fileDescriptor, option); err != nil { + return fmt.Errorf("create swagger apidocs error: %w", err) + } + log.Info("Generate the swagger apidocs of ```%s``` success", option.Protofile) + } + if option.OpenAPIOn { + if err := openapi.GenOpenAPI(fileDescriptor, option); err != nil { + return fmt.Errorf("create openapi apidocs error: %w", err) + } + log.Info("Generate the openapi apidocs of ```%s``` success", option.Protofile) + } + return nil +} + +func loadAPIDocsOptions(flagSet *pflag.FlagSet) (*params.Option, error) { + option := ¶ms.Option{} + + // Flags related to swagger. + option.SwaggerOn, _ = flagSet.GetBool("swagger") + option.SwaggerOptJSONParam, _ = flagSet.GetBool("swagger-json-param") + option.SwaggerOut, _ = flagSet.GetString("swagger-out") + + // Flags related to openapi. + option.OpenAPIOn, _ = flagSet.GetBool("openapi") + option.OpenAPIOut, _ = flagSet.GetString("openapi-out") + option.OrderByPBName, _ = flagSet.GetBool("order-by-pbname") + + // Proto files and search paths. + var err error + option.Protofile, err = flagSet.GetString("protofile") + if err != nil { + return nil, err + } + option.Protodirs, _ = flagSet.GetStringArray("protodir") + option.AliasOn, _ = flagSet.GetBool("alias") + + // Check if the pb file is valid. + if len(option.Protofile) == 0 { + return nil, errors.New("invalid protofile") + } + + // Locate the pb file. + target, err := fs.LocateFile(option.Protofile, option.Protodirs) + if err != nil { + return nil, err + } + option.Protofile = filepath.Base(target) + option.ProtofileAbs = target + option.Protodirs = append(option.Protodirs, filepath.Dir(target)) + option.IDLType = config.IDLTypeProtobuf + + // Adjust the search path for pb files. + if err := fixProtodirs(option); err != nil { + return nil, err + } + return option, nil +} + +// fixProtodirs fixes the search path for pb files. +func fixProtodirs(option *params.Option) error { + p, err := paths.Locate(pb.ProtoTRPC) + if err != nil { + return err + } + option.Protodirs = fs.UniqFilePath(append(append(option.Protodirs, p), + paths.ExpandSearch(p)...)) + return nil +} diff --git a/cmd/apidocs/apidocs_test.go b/cmd/apidocs/apidocs_test.go new file mode 100644 index 0000000..a790f2e --- /dev/null +++ b/cmd/apidocs/apidocs_test.go @@ -0,0 +1,77 @@ +package apidocs + +import ( + "os" + "path/filepath" + "testing" + + "trpc.group/trpc-go/trpc-cmdline/cmd/internal" +) + +func TestCmd_ApiDocs(t *testing.T) { + pwd, _ := os.Getwd() + defer func() { + os.Chdir(pwd) + }() + + wd := filepath.Dir(filepath.Dir(pwd)) + pbdir := filepath.Join(wd, "testcase/apidocs") + + if err := os.Chdir(pbdir); err != nil { + t.Fatal(err) + } + defer os.Chdir(wd) + + type testCase struct { + pb string + generated string + flags map[string]string + wantErr bool + } + + cases := []testCase{ + { + pb: "helloworld.proto", + generated: "helloworld.swagger.json", + flags: map[string]string{ + "protodir": ".", + "protofile": "helloworld.proto", + "swagger-out": "helloworld.swagger.json", + "check-update": "true", + }, + wantErr: false, + }, + { + pb: "helloworld.proto", + generated: "helloworld.openapi.json", + flags: map[string]string{ + "protodir": ".", + "protofile": "helloworld.proto", + "swagger": "false", + "openapi": "true", + "openapi-out": "helloworld.openapi.json", + "check-update": "true", + }, + wantErr: false, + }, + { + pb: "helloworld_restful.proto", + generated: "helloworld_restful.swagger.json", + flags: map[string]string{ + "swagger": "true", + "protofile": "helloworld_restful.proto", + "swagger-out": "helloworld_restful.swagger.json", + "check-update": "true", + }, + wantErr: false, + }, + } + apidocsCmd := CMD() + for _, arg := range cases { + generated := filepath.Join(pbdir, arg.generated) + defer os.Remove(generated) + if _, err := internal.RunAndWatch(apidocsCmd, arg.flags, nil); (err != nil) != arg.wantErr { + t.Errorf("apidocs cmd, wantErr = %v, got = %v", arg.wantErr, err) + } + } +} diff --git a/cmd/completion/completion.go b/cmd/completion/completion.go new file mode 100644 index 0000000..660c1d5 --- /dev/null +++ b/cmd/completion/completion.go @@ -0,0 +1,71 @@ +// Package completion provides completion command. +package completion + +import ( + "os" + + "github.com/spf13/cobra" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// CMD returns completion command. +// Users can run `trpc completion your_shell_name` to get script for auto-complete. +// To append to command to your shell environment, run +// +// `trpc completion your_shell_name >> your_shell_init_file` +func CMD() *cobra.Command { + completionCmd := &cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate shell autocompletion scripts", + Long: `Generate shell autocompletion scripts. Usage example: + +Bash: + +$ source <(yourprogram completion bash) + +# To load completions for each session, execute once: +Linux: + $ yourprogram completion bash > /etc/bash_completion.d/yourprogram +MacOS: + $ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram + +Zsh: + +# If shell completion is not already enabled in your environment you will need +# to enable it. You can execute the following once: + +$ echo "autoload -U compinit; compinit" >> ~/.zshrc + +# To load completions for each session, execute once: +$ yourprogram completion zsh > "${fpath[1]}/_yourprogram" + +# You will need to start a new shell for this Setup to take effect. + +Fish: + +$ yourprogram completion fish | source + +# To load completions for each session, execute once: +$ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish +`, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + cmd.Root().GenZshCompletion(os.Stdout) + case "fish": + cmd.Root().GenFishCompletion(os.Stdout, true) + case "powershell": + cmd.Root().GenPowerShellCompletion(os.Stdout) + default: + log.Error("%s is not supported", args[0]) + } + }, + } + return completionCmd +} diff --git a/cmd/completion/completion_test.go b/cmd/completion/completion_test.go new file mode 100644 index 0000000..9cd147b --- /dev/null +++ b/cmd/completion/completion_test.go @@ -0,0 +1,36 @@ +package completion + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/cmd/internal" +) + +func TestCmd_Completion(t *testing.T) { + completionCmd := CMD() + // bash + output, err := internal.RunAndWatch(completionCmd, nil, []string{"bash"}) + require.Nil(t, err) + require.NotEmpty(t, output) + //t.Logf("generated bash completion script: \n%s", output) + + // zsh + output, err = internal.RunAndWatch(completionCmd, nil, []string{"zsh"}) + require.Nil(t, err) + require.NotEmpty(t, output) + //t.Logf("generated zsh completion script: \n%s", output) + + // fish + output, err = internal.RunAndWatch(completionCmd, nil, []string{"fish"}) + require.Nil(t, err) + require.NotEmpty(t, output) + //t.Logf("generated fish completion script: \n%s", output) + + // powershell + output, err = internal.RunAndWatch(completionCmd, nil, []string{"powershell"}) + require.Nil(t, err) + require.NotEmpty(t, output) + //t.Logf("generated powershell completion script: \n%s", output) +} diff --git a/cmd/create/cmdflags.go b/cmd/create/cmdflags.go new file mode 100644 index 0000000..eb66e5f --- /dev/null +++ b/cmd/create/cmdflags.go @@ -0,0 +1,95 @@ +package create + +import "github.com/spf13/cobra" + +// AddCreateFlags adds flags to create sub command. +func AddCreateFlags(createCmd *cobra.Command) { + // There is stub code generated by idl (protobuf, flatbuffers). + // - pb + createCmd.Flags().StringArrayP("protodir", "d", []string{"."}, + "Search paths for pb files (including dependent pb files), can be specified multiple times") + createCmd.Flags().StringP("protofile", "p", "", "Specify the pb file corresponding to the service") + // - fb + createCmd.Flags().StringArray("fbsdir", []string{"."}, "Search paths for flatbuffers include files") + createCmd.Flags().String("fbs", "", "Specify the flatbuffers file corresponding to the service") + + // Whether to pass protoc/flatc by the basename of "--protofile/--fbs" provided above. + createCmd.Flags().Bool("usebasename", false, "Whether to pass the basename of --protofile/--fbs to protoc/flatc") + + // Generate stub code without IDL. + createCmd.Flags().StringP("non-protocol-type", "n", "", + "Generate project types without pb protocol support, supported types: kafka, http, hippo") + + // Select code template. + createCmd.Flags().String("assetdir", "", "Specify the custom template path, e.g., ~/.trpc-cmdline-assets/protobuf/asset_go") + createCmd.Flags().StringP("lang", "l", "go", + "Specify the programming language to use, supported languages: go") + createCmd.Flags().Bool("rpconly", false, + "Only generate stub code (recommended to execute under the stub directory), can be used with -o") + createCmd.Flags().Bool("dependencystub", false, + "Whether to generate stub code for dependencies, only effective when --rpconly=true, defaults to false") + createCmd.Flags().Bool("nogomod", false, + "Do not generate go.mod file in the stub code, only effective when --rpconly=true, defaults to false") + + // Add functionality similar to "protoc --go_out=. testdesc.proto --descriptor_set_in=testdesc.pb". + createCmd.Flags().StringP("descriptor_set_in", "", "", + "Similar to the same flag in protoc, can pass in the parsed descriptor_set to generate the project") + + // Parameters passed to template. + createCmd.Flags().String("protocol", "trpc", + "Specify the protocol type to use, supported types: trpc, http, etc") + createCmd.Flags().String("domain", "", + "Specify the code address domain to generate, defaults to the value specified in ~/.trpc-cmdline-assets/trpc.yaml") + createCmd.Flags().String("groupname", "trpc-go", + "Specify the code address group name to generate, defaults to trpc-go") + createCmd.Flags().String("versionsuffix", "", + "Specify the version suffix in the code address, "+ + "defaults to empty, can be set to v2, v3, etc. (effective for both the main library and dependencies)") + createCmd.Flags().Bool("multi-version", false, + "Multi-version protocol support, true: supported; false: not supported, "+ + "defaults to not support importing multiple version protocols") + createCmd.Flags().Bool("noservicesuffix", true, + "Whether the Service Descriptor naming in the generated Go stub code includes the Service suffix, "+ + "defaults to false") + addOutputFlags(createCmd) +} + +func addOutputFlags(createCmd *cobra.Command) { + // Controls related to output. + // Common options. + createCmd.Flags().StringP("output", "o", "", + "Specify the output directory (default: output to the directory with the same name as the pb file, "+ + "rpconly defaults to the current directory)") + createCmd.Flags().BoolP("force", "f", false, "Force overwrite existing code") + createCmd.Flags().StringP("mod", "m", "", "Specify the go module, default: trpc.app.${pb.package}") + createCmd.Flags().String("goversion", "1.12", "Specify the Go version in the generated go.mod file, default: 1.12") + createCmd.Flags().String("trpcgoversion", "", + "Specify the trpc-go version in the generated go.mod file") + createCmd.Flags().Bool("mock", true, + "Generate mock stub code (can be updated by running `go generate` in the project)") + + // Enable rpcname aliases. + createCmd.Flags().Bool("alias", false, "Use rpcname aliases") + + // Customize pb message struct tag. + createCmd.Flags().Bool("gotag", true, "Generate custom pb struct tag") + + // By default, files are split by service. + // If the following option is enabled, files will be split by RPC. + createCmd.Flags().BoolP("split-by-method", "s", false, "Whether to split files by method") + + // Whether to output Swagger documentation. + createCmd.Flags().Bool("swagger", false, "Generate Swagger API documentation") + createCmd.Flags().String("swagger-out", "apidocs.swagger.json", "Output file path for Swagger API documentation") + createCmd.Flags().Bool("swagger-json-param", false, + "Generate Swagger API documentation request parameters using JSON body") + + // Parameters related to git address. + createCmd.Flags().Bool("sync", false, + "Whether to sync git repository, default address: specified by go_package, can be specified by --remote") + createCmd.Flags().String("remote", "", "If sync git repository, specify the git repository address") + createCmd.Flags().Bool("newtag", false, "Whether to tag the uploaded repository") + createCmd.Flags().String("tag", "", + "If tagging the repository, specify the tag name. If not specified, "+ + "tag will be created in the format of v1.1.1, with rule of base 100") +} diff --git a/cmd/create/create.go b/cmd/create/create.go new file mode 100644 index 0000000..528340b --- /dev/null +++ b/cmd/create/create.go @@ -0,0 +1,315 @@ +// Package create provides create command. +package create + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/spf13/cobra" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/tpl" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// FD is an alias of descriptor.FileDescriptor. +type FD = descriptor.FileDescriptor + +// Create is for the create command. +type Create struct { + options *params.Option + fileDescriptor *descriptor.FileDescriptor + preRunHook func() error +} + +// CMD returns create command. +func CMD() *cobra.Command { + c := New(func() error { return nil }) + createCmd := &cobra.Command{ + Use: "create", + Short: "Quickly create projects or RPC stubs by specifying the pb file", + Long: `Quickly create projects or RPC stubs by specifying the pb file. + +'trpc create' has two modes: +- Generate a complete service project +- Generate RPC stubs for the target service, specify the '--rpconly' option +`, + PreRunE: c.PreRunE, + RunE: c.RunE, + PostRunE: c.PostRunE, + } + AddCreateFlags(createCmd) + return createCmd +} + +// New initializes a create command. +func New(preRunHook func() error) *Create { + return &Create{ + options: ¶ms.Option{}, + preRunHook: preRunHook, + } +} + +// PreRunE provides *cobra.Command.PreRunE. +func (c *Create) PreRunE(cmd *cobra.Command, args []string) error { + if err := c.loadOptions(cmd.Flags()); err != nil { + return fmt.Errorf("load create options inside pre run err: %w", err) + } + log.SetPrefix("[create]") + if err := c.preRunHook(); err != nil { + return fmt.Errorf("pre run hook err: %w", err) + } + // Non-pb type, pre run done. + if c.options.OtherType != "" { + return nil + } + var err error + opts := []parser.Option{ + parser.WithAliasOn(c.options.AliasOn), + parser.WithLanguage(c.options.Language), + parser.WithRPCOnly(c.options.RPCOnly), + parser.WithMultiVersion(c.options.MultiVersion), + } + if c.options.DescriptorSetIn != "" { + c.fileDescriptor, err = parser.LoadDescriptorSet( + c.options.DescriptorSetIn, + c.options.Protofile, + opts..., + ) + } else { + c.fileDescriptor, err = parser.Parse( + c.options.Protofile, + c.options.Protodirs, + c.options.IDLType, + opts..., + ) + } + if err != nil { + return fmt.Errorf("parser.Parse during pre run err: %w", err) + } + if c.options.Verbose { + c.fileDescriptor.Dump() + } + // Check and install dependencies. + return setup([]string{c.options.Language}) +} + +// RunE provides *cobra.Command.RunE. +func (c *Create) RunE(cmd *cobra.Command, args []string) error { + log.Debug("args: %v", args) + // Create a project of non protocol type. + if c.options.OtherType != "" { + return c.createByNonProtocolType() + } + return c.createByProtocolType() + +} + +func (c *Create) createByProtocolType() error { + outputDir, err := getOutputDir(c.options) + if err != nil { + return err + } + c.options.OutputDir = outputDir + // Create by IDL protocol type. + // Create a full project. + // if ignore RPCOnly flag, create a full project + if !c.options.RPCOnly || ignoreRPCOnly(c.options) { + return c.createFullProject() + } + // Create only rpc stub. + return c.createRPCOnlyStub() +} + +func (c *Create) createFullProject() (err error) { + dir := c.options.OutputDir + // Check whether the output path is clean. + if !isCleanDir(dir, c.options.IDLType, c.options.Language) && !c.options.Force { + return fmt.Errorf("%s is not empty, use a clean path or provide -f to force overwrite", dir) + } + + // Delete semi-finished files if anything wrong when + // generating a project from scratch. + var isNewDir bool + if _, err := os.Lstat(dir); err != nil && os.IsNotExist(err) { + isNewDir = true + } + defer func() { + if isNewDir && err != nil { + removeSafe(dir) + } + }() + + // Traverse each file in install/asset_${lang}. + if err := tpl.GenerateFiles(c.fileDescriptor, dir, c.options); err != nil { + return fmt.Errorf("generate files from template err: %w", err) + } + + // Generate IDL stub code for protobuf/flatbuffers. + if err := c.generateIDLStub(dir); err != nil { + return fmt.Errorf("generate rpc stub from template err: %w", err) + } + log.Info( + "Create tRPC project %s`%s`%s: succeed! ヾ(@^▽^@)ノ", + log.ColorRed, + fs.BaseNameWithoutExt(c.fileDescriptor.FilePath), + log.ColorGreen) + return nil +} + +// isCleanDir checks if generated files exist in the directory, and returns false if existed. +// Overwrite issues should be noted carefully +func isCleanDir(dir string, idlType config.IDLType, lang string) bool { + cfg, err := config.GetTemplate(idlType, lang) + if err != nil { + log.Error("config.GetTemplate failed when checking isCleanDir: %+v", err) + return false + } + return noFilesInLangExt(dir, cfg) +} + +func noFilesInLangExt(dir string, cfg *config.Template) bool { + // If the directory does not exist, it means there is no risk of file overwriting. + if _, err := os.Lstat(dir); err != nil { + return os.IsNotExist(err) + } + + // If the directory exists, then check whether "any" files exist in the directory. + // If existed, there is a risk of overwriting them. + files, err := os.ReadDir(dir) + if err != nil { + panic(err) + } + + ext := cfg.LangFileExt + for _, f := range files { + if strings.HasSuffix(f.Name(), ext) { + return false + } + } + + return true +} + +// removeSafe deletes the generated directory. +// Note that if the current directory is the output directory, +// it cannot be deleted. +// Returns true if deleted. +func removeSafe(path string) (bool, error) { + dir, err := os.Getwd() + if err != nil { + return false, err + } + if path == dir { + return false, nil + } + if err := os.RemoveAll(path); err != nil { + return false, err + } + return true, nil +} + +func (c *Create) createByNonProtocolType() error { + if err := c.checkCreateByNonProtocolType(); err != nil { + return err + } + + // Code generation. + // Preparing the output directory. + outputdir, err := getOutputDir(c.options) + if err != nil { + return err + } + + err = os.MkdirAll(outputdir, os.ModePerm) + if err != nil { + return err + } + + fd := &FD{ + PackageName: "trpc.app." + c.options.OtherType, + Services: []*descriptor.ServiceDescriptor{ + { + Name: c.options.OtherType, + }, + }, + AppName: c.options.OtherType, + } + c.fileDescriptor = &FD{ + FilePath: c.options.OtherType, + } + + if err = tpl.GenerateFiles(fd, outputdir, c.options); err != nil { + return err + } + + c.options.OutputDir = outputdir + return nil +} + +func (c *Create) checkCreateByNonProtocolType() error { + tmplPath := filepath.Join(c.options.Assetdir) + fileInfo, err := os.Stat(tmplPath) + if err != nil { + return fmt.Errorf("get template from path: %s, err: %w", tmplPath, err) + } + if !fileInfo.IsDir() { + return fmt.Errorf("%s is not a directory", tmplPath) + } + return nil +} + +// getOutputDir returns OutputDir. +// Note that error will be returned if you call os.Chdir and doesn't chdir back. +func getOutputDir(option *params.Option) (string, error) { + // 1. If `-o` is specified, use its value. + if option.OutputDir != "" { + if filepath.IsAbs(option.OutputDir) { + return option.OutputDir, nil + } + return filepath.Abs(option.OutputDir) + } + + // 2. If `-n` is specified, use its value, like http, kafka, etc. + if option.OtherType != "" { + return "trpc_" + option.OtherType + "_service", nil + } + + wd, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("get wd inside get output dir err: %w", err) + } + + // 3. If rpconly == true && not ignore rpcOnly flag, the default value is os.Getwd(). + if option.RPCOnly && !ignoreRPCOnly(option) { + return wd, nil + } + // 4, If rpconly == false, the default value is equal to the basename of protofile. + if option.GoModEx != "" && option.GoModEx == option.GoMod { + return wd, nil + } + return filepath.Join(wd, fs.BaseNameWithoutExt(option.Protofile)), nil +} + +func setup(languages []string) error { + if _, err := config.Init(); err != nil { + return err + } + deps, err := config.LoadDependencies(languages...) + if err != nil { + return err + } + return config.SetupDependencies(deps) +} + +// should ignore rpcOnly flag +func ignoreRPCOnly(option *params.Option) bool { + // cpp lang use bazel rule for generating stub code + return option.Language == "cpp" +} diff --git a/cmd/create/create_idl_fbs_test.go b/cmd/create/create_idl_fbs_test.go new file mode 100644 index 0000000..5149a47 --- /dev/null +++ b/cmd/create/create_idl_fbs_test.go @@ -0,0 +1,115 @@ +package create + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCreateCmdByFlatbuffers(t *testing.T) { + require.Nil(t, setup(nil)) + + wd, _ := os.Getwd() + defer func() { + os.Chdir(wd) + }() + + pd := filepath.Dir(wd) + pd = filepath.Dir(pd) + testdatadir := filepath.Join(pd, "testcase/flatbuffers") + + testcases := []testcase{ + { + name: "1.1-without-import", + pbdir: "1-without-import", + pbfile: "helloworld.fbs", + alias: true, + }, { + name: "1.2-without-import (rpconly)", + pbdir: "1-without-import", + pbfile: "helloworld.fbs", + rpconly: true, + }, { + name: "1.3-without-import (split by method)", + pbdir: "1-without-import", + pbfile: "helloworld.fbs", + splitByMethod: true, + }, { + name: "2-multi-fb-same-namespace", + pbdir: "2-multi-fb-same-namespace", + pbfile: "hello.fbs", + }, { + name: "3-multi-fb-diff-namespace", + pbdir: "3-multi-fb-diff-namespace", + pbfile: "helloworld.fbs", + }, { + name: "4.1-multi-fb-same-namespace-diff-dir", + pbdir: "4.1-multi-fb-same-namespace-diff-dir", + pbfile: "helloworld.fbs", + }, { + name: "4.2-multi-fb-same-namespace-diff-dir", + pbdir: "4.2-multi-fb-same-namespace-diff-dir", + pbfile: "helloworld.fbs", + }, { + name: "5-multi-fb-diff-gopkg fb", + pbdir: "5-multi-fb-diff-gopkg", + pbfile: "fbsread.fbs", + }, { + name: "5.1-multi-fb-diff-gopkg (split by method)", + pbdir: "5-multi-fb-diff-gopkg", + pbfile: "fbsread.fbs", + splitByMethod: true, + }, + } + + tmp := filepath.Join(os.TempDir(), "create/generated_fb") + os.RemoveAll(tmp) + defer os.RemoveAll(tmp) + + for _, tt := range testcases { + tt := tt + t.Run("CreateCmd/fbs-"+tt.name, func(t *testing.T) { + any := filepath.Join(testdatadir, tt.pbdir) + + if err := os.Chdir(any); err != nil { + panic(err) + } + + dirs := []string{} + err := filepath.Walk(any, func(path string, info os.FileInfo, _ error) error { + if info.IsDir() { + dirs = append(dirs, path) + } + return nil + }) + if err != nil { + panic("walk testcase error") + } + + opts := []string{} + for _, d := range dirs { + opts = append(opts, "--fbsdir", d) + } + opts = append(opts, "--fbs", tt.pbfile) + + out := filepath.Join(tmp, tt.name) + opts = append(opts, "-o", out) + + if tt.rpconly { + opts = append(opts, "--rpconly") + } + if tt.splitByMethod { + opts = append(opts, "-s") + } + if tt.alias { + opts = append(opts, "--alias") + } + opts = append(opts, "--mock", "false") + + resetFlags(createCmd) + runCreateCmd(t, "fbs "+tt.name, opts, out, tt.wantErr) + }) + } +} diff --git a/cmd/create/create_idl_non_test.go b/cmd/create/create_idl_non_test.go new file mode 100644 index 0000000..8fc3f5c --- /dev/null +++ b/cmd/create/create_idl_non_test.go @@ -0,0 +1,66 @@ +package create + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +type nonProtocolTypeArgs struct { + typ string + outdir string +} + +type nonProtocolTypeTestCase struct { + name string + args nonProtocolTypeArgs + wantErr bool +} + +func TestCreateCmdByNonProtocolType(t *testing.T) { + require.Nil(t, setup(nil)) + + pwd, _ := os.Getwd() + defer func() { + os.Chdir(pwd) + }() + + tests := setNonProtocolTypeTestCases() + + out := filepath.Join(os.TempDir(), "create/generated-non-protocol-type") + os.RemoveAll(out) + + for _, tt := range tests { + + opts := []string{} + + opts = append(opts, "--non-protocol-type", tt.args.typ) + outdir := filepath.Join(out, tt.args.typ) + opts = append(opts, "-o", outdir) + opts = append(opts, "--mock", "false") // No protocol types are needed for mock operations. + + resetFlags(createCmd) + runCreateCmd(t, tt.name, opts, outdir, tt.wantErr) + } +} + +func setNonProtocolTypeTestCases() []nonProtocolTypeTestCase { + tests := []nonProtocolTypeTestCase{ + { + "non-protocol-type-http", + nonProtocolTypeArgs{"http", "http"}, + false, + }, { + "non-protocol-type-kafka", + nonProtocolTypeArgs{"kafka", "kafka"}, + false, + }, { + "non-protocol-type-hippo", + nonProtocolTypeArgs{"hippo", "hippo"}, + false, + }, + } + return tests +} diff --git a/cmd/create/create_test.go b/cmd/create/create_test.go new file mode 100755 index 0000000..2a59bfe --- /dev/null +++ b/cmd/create/create_test.go @@ -0,0 +1,695 @@ +package create + +import ( + "errors" + "fmt" + + "math/rand" + "os" + "path/filepath" + "reflect" + "testing" + "unsafe" + + "github.com/agiledragon/gomonkey" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/plugin" + "trpc.group/trpc-go/trpc-cmdline/tpl" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +func TestMain(m *testing.M) { + if _, err := config.Init(); err != nil { + panic(err) + } + if err := setup(nil); err != nil { + panic(err) + } + os.Exit(m.Run()) +} + +// prepare testcases +type testcase struct { + name string + pbdir string + pbfile string + rpconly bool + splitByMethod bool + alias bool + lang string + wantErr bool +} + +func Test_CreateCmd(t *testing.T) { + wd, _ := os.Getwd() + defer os.Chdir(wd) + + pd := filepath.Dir(wd) + pd = filepath.Dir(pd) + testdir := filepath.Join(pd, "testcase/create") + testcases := []testcase{ + { + name: "1.1-without-import", + pbdir: "1-without-import", + pbfile: "helloworld.proto", + }, { + name: "1.2-without-import (alias)", + pbdir: "1-without-import", + pbfile: "helloworld.proto", + alias: true, + }, { + name: "1.3-without-import (rpconly)", + pbdir: "1-without-import", + pbfile: "helloworld.proto", + rpconly: true, + }, { + name: "1.5-without-import (split by method)", + pbdir: "1-without-import", + pbfile: "helloworld.proto", + splitByMethod: true, + }, { + name: "2-multi-pb-same-package", + pbdir: "2-multi-pb-same-package", + pbfile: "hello.proto", + }, { + name: "3-multi-pb-diff-package", + pbdir: "3-multi-pb-diff-package", + pbfile: "helloworld.proto", + }, { + name: "4.1-multi-pb-same-package-diff-protodir", + pbdir: "4.1-multi-pb-same-package-diff-protodir", + pbfile: "helloworld.proto", + }, { + name: "4.2-multi-pb-same-package-diff-protodir", + pbdir: "4.2-multi-pb-same-package-diff-protodir", + pbfile: "helloworld.proto", + }, { + name: "5-multi-pb-same-pkgdirective-diff-gopkgoption", + pbdir: "5-multi-pb-same-pkgdirective-diff-gopkgoption", + pbfile: "helloworld.proto", + }, { + name: "5.1-multi-pb-same-pkgdirective-diff-gopkgoption(split by method)", + pbdir: "5-multi-pb-same-pkgdirective-diff-gopkgoption", + pbfile: "helloworld.proto", + splitByMethod: true, + }, { + name: "6.1-other-scene google/protobuf/any", + pbdir: "6-other-scene/google", + pbfile: "google.proto", + }, { + name: "6.2-other-scene hello_service", + pbdir: "6-other-scene/hello_service", + pbfile: "hello.proto", + }, { + name: "8-service-not-existed", + pbdir: "8-service-not-existed", + pbfile: "helloworld.proto", + rpconly: true, + }, { + name: "9.1-restful (service)", + pbdir: "9-restful", + pbfile: "helloworld.proto", + }, { + name: "9.2-restful (rpconly)", + pbdir: "9-restful", + pbfile: "helloworld.proto", + rpconly: true, + }, + } + + tmp := filepath.Join(os.TempDir(), "create/generated") + os.RemoveAll(tmp) + // Reset plugin configuration. + // First, run create_idl_non_test.go, then execute setNonProtocolTypeOption, + // which modifies the global variables plugin.Plugins and plugin.PluginsExt. + // Finally, when running create_test.go test, it does not reset, causing the mockgan plugin not to run. + resetPlugin() + + // run createCmd + for _, tt := range testcases { + tt := tt + t.Run("CreateCmd/"+tt.name, func(t *testing.T) { + any := filepath.Join(testdir, tt.pbdir) + if err := os.Chdir(any); err != nil { + panic(err) + } + + dirs := []string{} + err := filepath.Walk(any, func(path string, info os.FileInfo, _ error) error { + if info.IsDir() { + dirs = append(dirs, path) + } + return nil + }) + if err != nil { + panic("walk testcase error") + } + + opts := []string{} + for _, d := range dirs { + opts = append(opts, "--protodir", d) + } + out := filepath.Join(tmp, tt.name) + opts = append(opts, "--protofile", tt.pbfile) + opts = append(opts, "-o", out) + opts = append(opts, "--check-update", "true") + + if tt.rpconly { + opts = append(opts, "--rpconly") + } + if tt.splitByMethod { + opts = append(opts, "-s") + } + if tt.alias { + opts = append(opts, "--alias") + } + if tt.lang != "" { + opts = append(opts, "--lang", tt.lang) + } + resetFlags(createCmd) + runCreateCmd(t, tt.name, opts, out, tt.wantErr) + }) + } +} + +var createCmd *cobra.Command + +func init() { + c := New(func() error { + return nil + }) + createCmd = &cobra.Command{ + Use: "create", + Short: "指定 pb 文件快速创建工程或 rpcstub", + Long: `指定 pb 文件快速创建工程或 rpcstub, + +'trpc create' 有两种模式: +- 生成一个完整的服务工程 +- 生成被调服务的 rpcstub, 需指定'--rpconly'选项 +`, + PreRunE: c.PreRunE, + RunE: c.RunE, + PostRunE: c.PostRunE, + } + var ( + cfgFile string + defaultConfigFile string + verboseFlag bool + checkUpdateFlag bool + ) + createCmd.PersistentFlags().StringVar(&cfgFile, "config", defaultConfigFile, "配置文件路径 (自动计算)") + createCmd.PersistentFlags().BoolVarP(&verboseFlag, "verbose", "v", false, "显示详细日志信息") + createCmd.PersistentFlags().BoolVar(&checkUpdateFlag, "check-update", false, "是否检查版本更新") + AddCreateFlags(createCmd) +} + +func resetPlugin() { + // Public plugin chain. + plugin.Plugins = []plugin.Plugin{ + &plugin.Swagger{}, // swagger apidoc + &plugin.OpenAPI{}, // openapi apidoc + &plugin.Validate{}, // protoc-gen-secv + } + // Language-specific plugin chain. + plugin.PluginsExt = map[string][]plugin.Plugin{ + "go": { + &plugin.GoImports{}, // goimports, runs before mockgen, to eliminate `package import but unused` errors + &plugin.Formatter{}, // gofmt + &plugin.GoMock{}, // gomock + &plugin.GoTag{}, // custom go tag by proto field options + }, + } +} + +func runCreateCmd(t *testing.T, name string, opts []string, out string, wantErr bool) { + if err := createCmd.ParseFlags(opts); err != nil { + t.Fatalf("TEST CreateCmd/%s ParseFlags error = %v", name, err) + } + if err := createCmd.PreRunE(createCmd, opts); (err != nil) != wantErr { + t.Fatalf("TEST CreateCmd/%s PreRunE() error = %v, wantErr %v", name, err, wantErr) + } + if err := createCmd.RunE(createCmd, opts); (err != nil) != wantErr { + t.Fatalf("TEST CreateCmd/%s RunE() error = %v, wantErr %v", name, err, wantErr) + } + + if _, err := os.Lstat(out); err != nil { + t.Fatalf("TEST CreateCmd/%s RunE() didn't generate output", name) + } + if err := createCmd.PostRunE(createCmd, opts); (err != nil) != wantErr { + t.Fatalf("TEST CreateCmd/%s PostRunE() error = %v, wantErr %v", name, err, wantErr) + } + if err := os.Chdir(out); (err != nil) != wantErr { + t.Fatalf("TEST CreateCmd/%s Chdir() error = %v, wantErr %v", name, err, wantErr) + } +} + +func resetFlags(cmd *cobra.Command) { + cmd.Flags().VisitAll(func(flag *pflag.Flag) { + if flag.Value.Type() == "stringSlice" { + // XXX: unfortunately, flag.Value.Set() appends to original + // slice, not resets it, so we retrieve pointer to the slice here + // and set it to new empty slice manually + value := reflect.ValueOf(flag.Value).Elem().FieldByName("value") + ptr := (*[]string)(unsafe.Pointer(value.Pointer())) + *ptr = make([]string, 0) + } + if flag.Value.Type() == "stringArray" { + // XXX: unfortunately, flag.Value.Set() appends to original + // slice, not resets it, so we retrieve pointer to the slice here + // and set it to new empty slice manually + value := reflect.ValueOf(flag.Value).Elem().FieldByName("value") + ptr := (*[]string)(unsafe.Pointer(value.Pointer())) + *ptr = make([]string, 0) + } + _ = flag.Value.Set(flag.DefValue) + }) + for _, cmd := range cmd.Commands() { + resetFlags(cmd) + } +} + +func TestCmd_Create_Exception(t *testing.T) { + // prepare workdir + pwd, err := os.Getwd() + require.Nil(t, err) + + dir := filepath.Dir(filepath.Dir(pwd)) + dir = filepath.Join(dir, "testcase/create/1-without-import") + if err := os.Chdir(dir); err != nil { + panic(err) + } + defer os.Chdir(pwd) + + // case1: invalid loadCreateOption (invalid --protofile) + out := "helloworld" + flags := map[string]string{ + "protodir": dir, + "protofile": "", + "mock": "false", + "output": out, + } + defer os.RemoveAll(filepath.Join(dir, out)) + + createCmd.ResetFlags() + _, err = runAndWatch(createCmd, flags, nil) + require.NotNil(t, err) + + // case2: proto parse error + p := gomonkey.ApplyFunc(parser.ParseProtoFile, func(string, []string, ...parser.Option) (*descriptor.FileDescriptor, error) { + return nil, errors.New("parse error") + }) + + flags = map[string]string{ + "protodir": dir, + "protofile": "helloworld.proto", + "mock": "false", + } + + _, err = runAndWatch(createCmd, flags, nil) + p.Reset() + + require.NotNil(t, err) +} + +func TestCreate_Exception(t *testing.T) { + t.Run("outputdir error", func(t *testing.T) { + p := gomonkey.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "", errors.New("get outputdir error") + }) + require.NotNil(t, (&Create{}).createByProtocolType()) + p.Reset() + }) + + t.Run("isCleanDir error", func(t *testing.T) { + p := gomonkey.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, idlType config.IDLType, c string) bool { + return false + }) + defer p.Reset() + require.NotNil(t, (&Create{options: ¶ms.Option{Language: "go"}}).createFullProject()) + }) + + t.Run("generate files error", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, b config.IDLType, c string) bool { + return true + }) + p.ApplyFunc(tpl.GenerateFiles, func(*descriptor.FileDescriptor, string, *params.Option) error { + return errors.New("generate files error") + }) + defer p.Reset() + require.NotNil(t, (&Create{options: ¶ms.Option{Language: "go"}}).createFullProject()) + }) + + t.Run("prepare outputdir error", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, b config.IDLType, c string) bool { + return true + }) + p.ApplyFunc(tpl.GenerateFiles, func(*descriptor.FileDescriptor, string, *params.Option) error { + return nil + }) + p.ApplyFunc(prepareOutputStub, func(string) (string, error) { + return "", errors.New("prepare outputdir error") + }) + defer p.Reset() + require.NotNil(t, (&Create{options: ¶ms.Option{Language: "go"}}).createFullProject()) + }) + + t.Run("get package error", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, b config.IDLType, c string) bool { + return true + }) + p.ApplyFunc(tpl.GenerateFiles, func(*descriptor.FileDescriptor, string, *params.Option) error { + return nil + }) + p.ApplyFunc(prepareOutputStub, func(string) (string, error) { + return "xxxx", nil + }) + p.ApplyFunc(parser.GetPackage, func(*descriptor.FileDescriptor, string) (string, error) { + return "", errors.New("get package error") + }) + defer p.Reset() + require.NotNil(t, (&Create{options: ¶ms.Option{Language: "go"}}).createFullProject()) + }) + + t.Run("mkdir all error", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, b config.IDLType, c string) bool { + return true + }) + p.ApplyFunc(tpl.GenerateFiles, func(*descriptor.FileDescriptor, string, *params.Option) error { + return nil + }) + p.ApplyFunc(prepareOutputStub, func(string) (string, error) { + return "xxxx", nil + }) + p.ApplyFunc(parser.GetPackage, func(*descriptor.FileDescriptor, string) (string, error) { + return "xxxx", nil + }) + p.ApplyFunc(os.MkdirAll, func(string, os.FileMode) error { + return errors.New("mkdirall error") + }) + defer p.Reset() + require.NotNil(t, (&Create{options: ¶ms.Option{Language: "go"}}).createFullProject()) + }) + + t.Run("run protoc error", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(getOutputDir, func(option *params.Option) (string, error) { + return "xxxxx", nil + }) + p.ApplyFunc(isCleanDir, func(a string, b config.IDLType, c string) bool { + return true + }) + p.ApplyFunc(tpl.GenerateFiles, func(*descriptor.FileDescriptor, string, *params.Option) error { + return nil + }) + p.ApplyFunc(prepareOutputStub, func(string) (string, error) { + return "xxxx", nil + }) + p.ApplyFunc(parser.GetPackage, func(*descriptor.FileDescriptor, string) (string, error) { + return "xxxx", nil + }) + p.ApplyFunc(os.MkdirAll, func(string, os.FileMode) error { + return nil + }) + p.ApplyFunc(pb.Protoc, func(protodirs []string, protofile, lang, outputdir string, opts ...pb.Option) error { + return errors.New("run protoc error") + }) + defer p.Reset() + require.NotNil(t, (&Create{ + fileDescriptor: &descriptor.FileDescriptor{}, + options: ¶ms.Option{Language: "go"}, + }).createFullProject()) + }) +} + +func Test_isCleanDir(t *testing.T) { + t.Run("dirty directory", func(t *testing.T) { + wd, err := os.Getwd() + if err != nil { + panic(err) + } + v := isCleanDir(wd, config.IDLTypeProtobuf, "go") + require.False(t, v) + }) + + t.Run("clean directory", func(t *testing.T) { + wd := os.TempDir() + tmp := filepath.Join(wd, "trpc") + os.RemoveAll(tmp) + os.MkdirAll(tmp, os.ModePerm) + defer os.RemoveAll(tmp) + v := isCleanDir(tmp, config.IDLTypeProtobuf, "go") + require.True(t, v) + }) +} + +func Test_removeSafe(t *testing.T) { + tmp := filepath.Join(os.TempDir(), "trpc") + + p := gomonkey.NewPatches() + p.ApplyFunc(os.Getwd, func() (dir string, err error) { + return tmp, nil + }) + + rm, err := removeSafe(tmp) + require.Nil(t, err) + require.False(t, rm) + + p.Reset() + rm, err = removeSafe(tmp) + require.Nil(t, err) + require.True(t, rm) +} + +func Test_prepareOutputDir(t *testing.T) { + a := os.TempDir() + b := "b" + c := "hello" + + p := gomonkey.ApplyFunc(os.MkdirAll, func(string, os.FileMode) error { + return nil + }) + defer p.Reset() + t.Run("prepare go outputdir", func(t *testing.T) { + d, err := prepareOutputDir(a, b, "go", c) + require.Nil(t, err) + require.Equal(t, filepath.Join(a, b), d) + }) +} + +func Test_prepareOutputStubDir(t *testing.T) { + tmp := os.TempDir() + stub := filepath.Join(tmp, "stub") + + t.Run("stub notExist, create", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.MkdirAll, func(string, os.FileMode) error { + return nil + }) + defer p.Reset() + + dir, err := prepareOutputStub(tmp) + require.Nil(t, err) + require.Equal(t, stub, dir) + }) + + t.Run("stub exist, return", func(t *testing.T) { + os.MkdirAll(stub, os.ModePerm) + defer os.RemoveAll(stub) + + dir, err := prepareOutputStub(tmp) + require.Nil(t, err) + require.Equal(t, stub, dir) + }) + + t.Run("stub lstat error", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Lstat, func(string) (os.FileInfo, error) { + return nil, errors.New("lstat error") + }) + _, err := prepareOutputStub(tmp) + require.NotNil(t, err) + p.Reset() + }) +} + +func TestOutputDir(t *testing.T) { + + t.Run("case os.Getwd error", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "", errors.New("fake error") + }) + defer p.Reset() + opts := ¶ms.Option{} + dir, err := getOutputDir(opts) + require.NotNil(t, err) + require.Empty(t, dir) + }) + + t.Run("case rpconly abs", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd", nil + }) + defer p.Reset() + opts := ¶ms.Option{ + RPCOnly: true, + OutputDir: "/is_abs", + } + dir, err := getOutputDir(opts) + require.Nil(t, err) + require.Equal(t, "/is_abs", dir) + }) + + t.Run("case rpconly not abs", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd", nil + }) + defer p.Reset() + opts := ¶ms.Option{ + RPCOnly: true, + OutputDir: "is_not_abs", + } + dir, err := getOutputDir(opts) + require.Nil(t, err) + require.Equal(t, "wd/is_not_abs", dir) + }) + + t.Run("case not rpconly with -o", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd", nil + }) + defer p.Reset() + opts := ¶ms.Option{ + RPCOnly: false, + OutputDir: "outputdir", + } + dir, err := getOutputDir(opts) + require.Nil(t, err) + require.Equal(t, "wd/outputdir", dir) + }) + + t.Run("case not rpconly with mod", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd", nil + }) + defer p.Reset() + opts := ¶ms.Option{ + RPCOnly: false, + GoModEx: "mod", + GoMod: "mod", + OutputDir: "", + } + dir, err := getOutputDir(opts) + require.Nil(t, err) + require.Equal(t, "wd", dir) + }) + + t.Run("case not rpconly with mod", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd", nil + }) + defer p.Reset() + opts := ¶ms.Option{ + RPCOnly: false, + GoModEx: "", + GoMod: "", + OutputDir: "", + Protofile: "filename.proto", + IDLType: config.IDLTypeProtobuf, + } + dir, err := getOutputDir(opts) + require.Nil(t, err) + require.Equal(t, "wd/filename", dir) + }) +} + +func runAndWatch(cmd *cobra.Command, flags map[string]string, args []string) (string, error) { + n := rand.Int() % 65535 + tmp := os.TempDir() + tmpd := filepath.Join(tmp, "trpc") + tmpf := filepath.Join(tmpd, fmt.Sprintf("cmd_output-%d", n)) + + os.MkdirAll(tmpd, os.ModePerm) + defer os.RemoveAll(tmpd) + + f, err := os.OpenFile(tmpf, os.O_CREATE|os.O_RDWR, 0666) + if err != nil { + panic(err) + } + defer os.RemoveAll(tmpf) + + sout := os.Stdout + serr := os.Stderr + + os.Stdout = f + os.Stderr = f + defer func() { + os.Stdout = sout + os.Stderr = serr + }() + + for k, v := range flags { + cmd.Flags().Set(k, v) + } + + // PreRun + if cmd.PreRunE != nil { + err = cmd.PreRunE(cmd, args) + if err != nil { + return "", err + } + } else if cmd.PreRun != nil { + cmd.PreRun(cmd, args) + } + + // Run + if cmd.RunE != nil { + err = cmd.RunE(cmd, args) + if err != nil { + return "", err + } + } else if cmd.Run != nil { + cmd.Run(cmd, args) + } + + // PostRun + if cmd.PostRunE != nil { + err = cmd.PostRunE(cmd, args) + if err != nil { + return "", err + } + } else if cmd.PostRun != nil { + cmd.PostRun(cmd, args) + } + + f.Close() + + b, err := os.ReadFile(tmpf) + if err != nil { + return "", err + } + return string(b), nil +} diff --git a/cmd/create/generate.go b/cmd/create/generate.go new file mode 100644 index 0000000..60b1d2f --- /dev/null +++ b/cmd/create/generate.go @@ -0,0 +1,466 @@ +package create + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/pkg/errors" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/fb" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/log" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +// generateIDLStub generates *.pb.go under outputdir/rpc/. +func (c *Create) generateIDLStub(dir string) error { + // Cpp IDL stub code will be generated using bazel rules, do nothing here. + if c.options.Language == "cpp" { + return nil + } + + fd, options := c.fileDescriptor, c.options + stubdir, err := prepareOutputStub(dir) + if err != nil { + return fmt.Errorf("prepare output stub: %w", err) + } + + pkg, err := parser.GetPackage(fd, options.Language) + if err != nil { + return fmt.Errorf("parser get package: %w", err) + } + + if err := generatePBFB(fd, options, pkg, stubdir); err != nil { + return fmt.Errorf("generate pb fb: %w", err) + } + + if !options.RPCOnly || options.DependencyStub { + if err := handleDependencies(fd, options, pkg, stubdir); err != nil { + return fmt.Errorf("handle dependencies: %w", err) + } + } + + // Move dir/rpc into dir/$gopkgdir/. + src := filepath.Join(dir, "rpc") + dest := filepath.Join(stubdir, pkg) + defer os.RemoveAll(src) + + return filepath.Walk(src, func(fpath string, _ os.FileInfo, _ error) (e error) { + if fpath == src { + return nil + } + if fname := filepath.Base(fpath); fname == "trpc.go" { + return fs.Move(fpath, filepath.Join(dest, fs.BaseNameWithoutExt(fd.FilePath)+".trpc.go")) + } + return fs.Move(fpath, filepath.Join(dest, filepath.Base(fpath))) + }) +} + +func prepareOutputStub(outputdir string) (string, error) { + stubDir := filepath.Join(outputdir, "stub") + + if _, err := os.Lstat(stubDir); err != nil { + if !os.IsNotExist(err) { + return "", err + } + if err := os.Mkdir(stubDir, os.ModePerm); err != nil { + return "", err + } + return stubDir, nil + } + return stubDir, nil +} + +// generatePBFB generates stub code based on option.IDLType by calling runProtoc or runFlatc. +func generatePBFB(fd *FD, option *params.Option, packageName, stubDir string) error { + out := filepath.Join(stubDir, packageName) + if err := os.MkdirAll(out, os.ModePerm); err != nil { + return err + } + if option.IDLType == config.IDLTypeProtobuf { + log.Debug("generate code for file %s from %v into %s", option.Protofile, option.Protodirs, out) + // Invoke protoc and copy the .proto file to the generated folder. + return protocAndCopy(fd, option, out) + } + log.Debug("generate code for file %s into %s", option.Protofile, out) + // Invoke flatc and copy the .fbs file to the generated folder. + return flatcAndCopy(fd, option, out) +} + +// protocAndCopy invokes runProtoc and copies the .proto file to the generated folder. +func protocAndCopy(fd *FD, option *params.Option, pbOutDir string) error { + if _, err := runProtoc(fd, pbOutDir, option); err != nil { + return fmt.Errorf("run protoc err: %w", err) + } + if option.DescriptorSetIn != "" { + // When passing in the descriptor_set_in parameter, skip copying the .proto file as it does not exist. + return nil + } + // copy *.proto to outpoutdir/rpc/ + basename := filepath.Base(fd.FilePath) + return fs.Copy(fd.FilePath, filepath.Join(pbOutDir, basename)) +} + +// runProtoc sets the required options and invokes util/pb.Protoc for processing. +func runProtoc(fd *FD, pbOutDir string, option *params.Option) ([]string, error) { + opts := []pb.Option{ + pb.WithPb2ImportPath(fd.Pb2ImportPath), + pb.WithPkg2ImportPath(fd.Pkg2ImportPath), + pb.WithDescriptorSetIn(option.DescriptorSetIn), + } + + var files []string + + // run protoc --$lang_out + if err := pb.Protoc(option.Protodirs, option.Protofile, option.Language, pbOutDir, opts...); err != nil { + return nil, fmt.Errorf("run protoc --$lang_out err: %v", err) + } + + // run protoc-gen-secv + opts = append(opts, pb.WithSecvEnabled(true)) + if err := pb.Protoc(option.Protodirs, option.Protofile, option.Language, pbOutDir, opts...); err != nil { + return nil, fmt.Errorf("run protoc-gen-secv err: %v", err) + } + log.Debug("pbOutDir = %s", pbOutDir) + // collect the generated files + matches, err := filepath.Glob(pbOutDir) + if err != nil { + return nil, fmt.Errorf("filepath glob pb out dir: %s, err: %w", pbOutDir, err) + } + for _, v := range matches { + if v == pbOutDir { + continue + } + inf, err := os.Lstat(v) + if err != nil { + continue + } + if inf.IsDir() { + continue + } + files = append(files, v) + } + + return files, nil +} + +// runFlatc sets the required options and invokes util.fb.Flatc. +func runFlatc(fd *FD, fbsOutDir string, option *params.Option) ([]string, error) { + opts := []fb.Option{ + fb.WithFbsDirs(option.Protodirs), + fb.WithFbsfile(option.Protofile), + fb.WithLanguage(option.Language), + fb.WithPackagePath(fd.BaseGoPackageName), + fb.WithOutputdir(fbsOutDir), + fb.WithFb2ImportPath(fd.Pb2ImportPath), + fb.WithPkg2ImportPath(fd.Pkg2ImportPath), + } + // FIXME, return generate filenames + return nil, fb.NewFbs(opts...).Flatc() +} + +// flatcAndCopy constructs the parameter list and invokes fb.Flatc to generate stub code for each type in the .fbs file. +// Then, the .fbs file is copied to the generated folder. +func flatcAndCopy(fd *FD, option *params.Option, outdir string) error { + if _, err := runFlatc(fd, outdir, option); err != nil { + return err + } + + // The basename is in the form of "file1.fbs". + basename := filepath.Base(fd.FilePath) + + // Copy the *.fbs file to the directory where the generated files are located. + return fs.Copy(fd.FilePath, filepath.Join(outdir, basename)) +} + +// handleDependencies processes other pb files imported by the pb files specified in the "-protofile" option. +// It also processes protoc and copies pb files. +// +// Preparing to generate *.pb.go files corresponding to the PB files using protoc. +// Note that to avoid generating code with circular dependencies. +// +// Parse the result using jhump/protoreflect. +// If the pkgname is the same as the one specified in "-protofile", the importpath will be "". +// +// runProtoc --go_out=M$pb=$pkgname, we need to do compatibility processing: +// 1. Avoid passing $pkgname as empty, otherwise protoc will generate code like this.: +// ```go +// package $pkgname +// import ( +// "." +// ) +// ``` +// 2. Avoid passing the same pkgname as -protofile, otherwise it will cause circular dependencies. +// ```go +// package $pkgname +// import ( +// "$pkgname" +// ) +// ``` +func handleDependencies(fd *FD, option *params.Option, pbpkg string, outputDir string) error { + outputDir, err := filepath.Abs(outputDir) + if err != nil { + return fmt.Errorf("filepath abs output dir: %s, err: %w", outputDir, err) + } + + wd, err := os.Getwd() + if err != nil { + return fmt.Errorf("os get working directory err: %w", err) + } + defer os.Chdir(wd) + + return doHandleDependencies(fd, pbpkg, outputDir, wd, option) +} + +func doHandleDependencies(fd *FD, pbpkg, outputDir, wd string, option *params.Option) error { + includeDirs := genIncludeDirs(fd) + for fname, importPath := range fd.Pb2ImportPath { + if skipThisProtofile(fd, fname) { + continue + } + + param := &genDependencyRPCStubParam{ + fd: fd, + option: option, + pbpkg: pbpkg, + outputDir: outputDir, + fname: fname, + importPath: importPath, + wd: wd, + includeDirs: includeDirs, + } + param.importPath = lang.TrimRight(";", param.importPath) + pbOutDir, err := param.genDependencyRPCStub() + if err != nil { + return fmt.Errorf("generate dependency rpc stub err: %w", err) + } + importPath = lang.TrimRight(";", importPath) + if err := moduleInit(option, pbpkg, fname, importPath, pbOutDir); err != nil { + return fmt.Errorf("module init err: %w", err) + } + } + return nil +} + +func genIncludeDirs(fd *FD) []string { + includeDirs := []string{} + for fname := range fd.Pb2ImportPath { + dir, _ := filepath.Split(fname) + includeDirs = append(includeDirs, dir) + } + return includeDirs +} + +func skipThisProtofile(fd *FD, fname string) bool { + // If it is ${protofile}, skip and do not process it. + if filepath.Base(fd.FilePath) == fname { + return true + } + + // Skip the pb files, trpc extension files, and swagger extension files provided by Google. + return pb.IsInternalProto(fname) +} + +type genDependencyRPCStubParam struct { + fd *FD + option *params.Option + pbpkg string + outputDir string + fname string + importPath string + wd string + includeDirs []string +} + +func (g *genDependencyRPCStubParam) genDependencyRPCStub() (string, error) { + var err error + + g.outputDir, err = prepareOutputDir(g.outputDir, g.importPath, g.option.Language, g.pbpkg) + if err != nil { + return "", fmt.Errorf("prepare output dir, err: %w", err) + } + + switch g.option.IDLType { + case config.IDLTypeProtobuf: + err = g.genDependencyRPCStubPB() + case config.IDLTypeFlatBuffers: + err = g.genDependencyRPCStubFB() + default: + return "", errors.New("invalid IDL type") + } + + return g.outputDir, err +} + +func prepareOutputDir(outputDir, importPath, lang, pbPackage string) (string, error) { + var pbOutDir string + if lang == "go" { + pbOutDir = filepath.Join(outputDir, importPath) + } else { + pbOutDir = filepath.Join(outputDir, pbPackage) + } + if err := os.MkdirAll(pbOutDir, os.ModePerm); err != nil { + return "", err + } + return pbOutDir, nil +} + +func (g *genDependencyRPCStubParam) genDependencyRPCStubPB() error { + // Inherit the directory from the parent level to avoid directory not found issues. + searchPath, err := genProtocProtoPath(g.option, g.wd, g.includeDirs) + if err != nil { + return fmt.Errorf("generate protoc proto path err: %w", err) + } + log.Debug("Generate code for proto file %s from %v into %s", g.fname, searchPath, g.outputDir) + + // run protoc-gen-go + opts := []pb.Option{ + pb.WithPb2ImportPath(g.fd.Pb2ImportPath), + pb.WithPkg2ImportPath(g.fd.Pkg2ImportPath), + pb.WithDescriptorSetIn(g.option.DescriptorSetIn), + } + if err = pb.Protoc(searchPath, g.fname, g.option.Language, g.outputDir, opts...); err != nil { + return fmt.Errorf("GenerateFiles: %v", err) + } + + // run protoc-gen-secv + opts = append(opts, pb.WithSecvEnabled(true)) + if err = pb.Protoc(searchPath, g.fname, g.option.Language, g.outputDir, opts...); err != nil { + return fmt.Errorf("GenerateFiles: %v", err) + } + if g.option.DescriptorSetIn != "" { + return nil // skip copy if descriptor_set_in is passed. + } + + // Copy pb file. + if err := copyProtofile(g.fname, g.outputDir, g.option); err != nil { + return fmt.Errorf("copy proto file err: %w", err) + } + return nil +} + +func genProtocProtoPath(option *params.Option, wd string, includeDirs []string) ([]string, error) { + searchPath := option.Protodirs + parentDirs := []string{wd} + parentDirs = append(parentDirs, option.Protodirs...) + for _, pDir := range parentDirs { + newSearchPath, err := genProtocProtoPathByParentDir(includeDirs, pDir) + if err != nil { + return nil, err + } + searchPath = append(searchPath, newSearchPath...) + } + return fs.UniqFilePath(searchPath), nil +} + +func genProtocProtoPathByParentDir(includeDirs []string, pDir string) ([]string, error) { + var searchPath []string + for _, incDir := range includeDirs { + + includeDir := filepath.Join(pDir, incDir) + includeDir = filepath.Clean(includeDir) + + if fin, err := os.Lstat(includeDir); err != nil { + if !os.IsNotExist(err) { + return nil, fmt.Errorf("os lstat err err: %w", err) + } + } else { + if !fin.IsDir() { + return nil, fmt.Errorf("import path: %s, not directory", includeDir) + } + searchPath = append(searchPath, includeDir) + } + } + return searchPath, nil +} + +func copyProtofile(fname, pbOutDir string, option *params.Option) error { + p, err := fs.LocateFile(fname, option.Protodirs) + if err != nil { + return fmt.Errorf("fs locate file err: %w", err) + } + + _, baseName := filepath.Split(fname) + src := p + dst := filepath.Join(pbOutDir, baseName) + + log.Debug("Copy file %s to %s", src, dst) + if err := fs.Copy(src, dst); err != nil { + return err + } + return nil +} + +func (g *genDependencyRPCStubParam) genDependencyRPCStubFB() error { + strs := strings.Split(g.importPath, "/") + baseGoPackageName := strs[len(strs)-1] + filename, err := fs.LocateFile(g.fname, g.option.Protodirs) + if err != nil { + return fmt.Errorf("cannot locate file %v: %v", g.fname, err) + } + opts := []fb.Option{ + fb.WithFbsDirs(g.option.Protodirs), + fb.WithFbsfile(filename), + fb.WithLanguage(g.option.Language), + fb.WithPackagePath(baseGoPackageName), + fb.WithOutputdir(g.outputDir), + fb.WithFb2ImportPath(g.fd.Pb2ImportPath), + fb.WithPkg2ImportPath(g.fd.Pkg2ImportPath), + } + f := fb.NewFbs(opts...) + if err := f.Flatc(); err != nil { + return fmt.Errorf("flatc: %v", err) + } + // Copy fbs file. + _, baseName := filepath.Split(filename) + src := filename + dst := filepath.Join(g.outputDir, baseName) + log.Debug("Copy file %s to %s", src, dst) + if err := fs.Copy(src, dst); err != nil { + return err + } + return nil +} + +func moduleInit(option *params.Option, pbpkg string, fname string, importPath string, pbOutDir string) error { + // Fixme: move to createCmd.PostRun + // Run "go mod init". If it is the same as pbPackage, no initialization is required. + if option.Language != "go" { + return nil + } + + return genGoModInit(importPath, pbpkg, pbOutDir, fname) +} + +func genGoModInit(importPath, pbPackage, pbOutDir, fname string) error { + // Initialize go.mod to avoid duplicating initialization of go.mod. + fp := filepath.Join(pbOutDir, "go.mod") + fin, err := os.Stat(fp) + if err == nil && !fin.IsDir() { + return nil + } + + // Run "go mod init". + if !canExecGoModInit(importPath, pbPackage) { + return nil + } + _ = os.Chdir(pbOutDir) + + cmd := exec.Command("go", "mod", "init", importPath) + if buf, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("process %s, init go.mod in stub/%s error: %v", fname, importPath, string(buf)) + } + log.Debug("process %s, init go.mod success in stub/%s: go mod init %s", fname, importPath, importPath) + return nil +} + +func canExecGoModInit(importPath string, pbPackage string) bool { + return len(importPath) != 0 && importPath != pbPackage +} diff --git a/cmd/create/options.go b/cmd/create/options.go new file mode 100644 index 0000000..a43ec72 --- /dev/null +++ b/cmd/create/options.go @@ -0,0 +1,415 @@ +package create + +import ( + "fmt" + "path/filepath" + + "github.com/pkg/errors" + "github.com/spf13/pflag" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/plugin" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/paths" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +// loadOptions loads options from flags. +func (c *Create) loadOptions(flags *pflag.FlagSet) error { + if err := c.parse(flags); err != nil { + return fmt.Errorf("load options err: %w", err) + } + if err := c.fixOptions(); err != nil { + return fmt.Errorf("fix create options inside prerun err: %w", err) + } + return nil +} + +// parse verifies and parses the flags. +func (c *Create) parse(flags *pflag.FlagSet) error { + if err := c.parseIDLOptions(flags); err != nil { + return fmt.Errorf("parse idl options err: %w", err) + } + + if err := c.parseGeneralOptions(flags); err != nil { + return fmt.Errorf("parse general options err: %w", err) + } + + if err := c.parseSwaggerOptions(flags); err != nil { + return fmt.Errorf("parse swagger options err: %w", err) + } + + if err := c.parseProtocolOptions(flags); err != nil { + return fmt.Errorf("parse protocol options err: %w", err) + } + + if err := c.parseAuxiliaryOptions(flags); err != nil { + return fmt.Errorf("parse auxiliary options err: %w", err) + } + + if err := c.parseSyncGitOptions(flags); err != nil { + return fmt.Errorf("parse sync git options err: %w", err) + } + return nil +} + +// fixOptions fixes the options. +func (c *Create) fixOptions() error { + c.fixGoMod() + if err := c.fixIDL(); err != nil { + return fmt.Errorf("fix idl err: %w", err) + } + return nil +} + +// fixGoMod fixes the module name. +func (c *Create) fixGoMod() { + // 1. Use module name specified by -mod. + // 2. Use local go.mod if -mod is not specified (for backward compatibility). + // 3. Use package name defined in pb (implemented by template). + if c.options.GoMod != "" { + return + } + mod, err := lang.LoadGoMod() + if err != nil { + return + } + if mod == "" { + return + } + c.options.GoModEx = mod + c.options.GoMod = mod + return +} + +// fixIDL fixes the IDL. +func (c *Create) fixIDL() error { + if c.options.OtherType != "" { + return c.fixOtherType() // Non-IDL type, such as kafka, HTTP. + } + if c.options.Protofile == "" { + return errors.New("protobuf/flatbuffers file both empty") + } + if err := c.fixProtoDirs(); err != nil { + return fmt.Errorf("fix proto dirs err: %w", err) + } + return c.fixProtocolType() +} + +// fixOtherType updates the options related to "OtherType". +func (c *Create) fixOtherType() error { + installPath, err := config.CurrentTemplatePath() + if err != nil { + return fmt.Errorf("failed to get current template path for other type err: %w", err) + } + + if c.options.Assetdir == "" { // Do not override options provided by the user. + c.options.Assetdir = filepath.Join(installPath, "without_idl", c.options.Language, c.options.OtherType) + } + + c.options.Protocol = c.options.OtherType + // May consider using c.options.OutputDir here. + + c.options.Protofile = c.options.OtherType + + // Plugins for code generation. + plugin.Plugins = []plugin.Plugin{ + &plugin.GoImports{}, // goimports, runs before mockgen, to eliminate `package import but unused` errors + &plugin.Formatter{}, // gofmt + } + + plugin.PluginsExt[c.options.Language] = nil + + return nil +} + +// fixProtoDirs updates the options related to proto directories. +// If DescriptorSetIn is provided, it locates the file and updates the file path. +// Otherwise, it locates the proto file and updates the options accordingly. +func (c *Create) fixProtoDirs() error { + if c.options.DescriptorSetIn != "" { + var err error + filePath, err := fs.LocateFile(c.options.DescriptorSetIn, nil) + if err != nil { + return fmt.Errorf("fs locate file %s err: %w", c.options.DescriptorSetIn, err) + } + c.options.DescriptorSetIn = filePath + return nil + } + + p, err := paths.Locate(pb.ProtoTRPC) + if err != nil { + return fmt.Errorf("paths local trpc failed err: %w", err) + } + + c.options.Protodirs = fs.UniqFilePath(append(append(c.options.Protodirs, p), + paths.ExpandSearch(p)..., + )) + + target, err := fs.LocateFile(c.options.Protofile, c.options.Protodirs) + if err != nil { + return fmt.Errorf("locate file in proto dirs failed err: %w", err) + } + + if c.options.UseBaseName { + c.options.Protofile = filepath.Base(target) + } + + c.options.ProtofileAbs = target + c.options.Protodirs = append(c.options.Protodirs, filepath.Dir(target)) + + return nil +} + +// fixProtocolType updates the options related to the protocol type. +// It loads configurations from trpc.yaml and updates the options accordingly. +func (c *Create) fixProtocolType() error { + // Load configurations from trpc.yaml. + cfg, err := config.GetTemplate(c.options.IDLType, c.options.Language) + if err != nil { + return fmt.Errorf("config get template failed err: %w", err) + } + if c.options.Assetdir == "" { + c.options.Assetdir = cfg.AssetDir + } + if c.options.Domain == "" { + c.options.Domain = config.GlobalConfig().Domain + } + if c.options.VersionSuffix != "" { + c.options.VersionSuffix = "/" + c.options.VersionSuffix + } + return nil +} + +// parseIDLOptions parses the IDL-related options from the command line flags. +// It parses the "usebasename" flag and delegates to other functions to parse protobuf/flatbuffers options. +func (c *Create) parseIDLOptions(flags *pflag.FlagSet) error { + var err error + c.options.UseBaseName, err = flags.GetBool("usebasename") + if err != nil { + return fmt.Errorf("flags parse usebasename %w", err) + } + // Parse protobuf/flatbuffers options. + if err := c.parsePBIDLOptions(flags); err != nil { + return fmt.Errorf("flags parse pb idl options err: %w", err) + } + // If protofile field is empty, try parse flatbuffers related flags. + if c.options.Protofile == "" { + if err := c.parseFBIDLOptions(flags); err != nil { + return fmt.Errorf("flags parse fb idl options, err: %w", err) + } + } + return nil +} + +// parseGeneralOptions parses the general options from the command line flags. +// It parses the "verbose" flag and delegates to other functions to parse input/output options. +func (c *Create) parseGeneralOptions(flags *pflag.FlagSet) error { + var err error + c.options.Verbose, err = flags.GetBool("verbose") + if err != nil { + return fmt.Errorf("flags parse verbose string err: %w", err) + } + if err := c.parseInputOptions(flags); err != nil { + return err + } + if err := c.parseOutputOptions(flags); err != nil { + return err + } + return nil +} + +// parseAuxiliaryOptions parses the auxiliary options from the command line flags. +// It parses various boolean and string flags related to auxiliary options. +func (c *Create) parseAuxiliaryOptions(flags *pflag.FlagSet) error { + var err error + c.options.MultiVersion, err = flags.GetBool("multi-version") + if err != nil { + return fmt.Errorf("flags parse multi-version bool err: %w", err) + } + c.options.NoServiceSuffix, err = flags.GetBool("noservicesuffix") + if err != nil { + return fmt.Errorf("flags parse noservicesuffix bool err: %w", err) + } + return nil +} + +// parseInputOptions parses the input options from the command line flags. +// It parses various string and boolean flags related to input options. +func (c *Create) parseInputOptions(flags *pflag.FlagSet) error { + var err error + c.options.Assetdir, err = flags.GetString("assetdir") + if err != nil { + return fmt.Errorf("flags parse assetdir string err: %w", err) + } + c.options.Language, err = flags.GetString("lang") + if err != nil { + return fmt.Errorf("flags parse lang string err: %w", err) + } + c.options.AliasOn, err = flags.GetBool("alias") + if err != nil { + return fmt.Errorf("flags parse alias bool err: %w", err) + } + c.options.GoMod, err = flags.GetString("mod") + if err != nil { + return fmt.Errorf("flags parse mod string err: %w", err) + } + c.options.GoVersion, err = flags.GetString("goversion") + if err != nil { + return fmt.Errorf("flags parse goversion string err: %w", err) + } + c.options.TRPCGoVersion, err = flags.GetString("trpcgoversion") + if err != nil { + return fmt.Errorf("flags parse trpcgoversion string err: %w", err) + } + c.options.DescriptorSetIn, err = flags.GetString("descriptor_set_in") + if err != nil { + return fmt.Errorf("flags parse descriptor_set_in string err: %w", err) + } + return nil +} + +// parseOutputOptions parses the output options from the command line flags. +// It parses various string and boolean flags related to output options. +func (c *Create) parseOutputOptions(flags *pflag.FlagSet) error { + var err error + c.options.OutputDir, err = flags.GetString("output") + if err != nil { + return fmt.Errorf("flags parse output string err: %w", err) + } + c.options.RPCOnly, err = flags.GetBool("rpconly") + if err != nil { + return fmt.Errorf("flags parse rpconly bool err: %w", err) + } + c.options.DependencyStub, err = flags.GetBool("dependencystub") + if err != nil { + return fmt.Errorf("flags parse dependencystub %w", err) + } + c.options.NoGoMod, err = flags.GetBool("nogomod") + if err != nil { + return fmt.Errorf("flags parse nogomod bool err: %w", err) + } + c.options.KeepOrigRPCName = true // Always true. + c.options.Force, err = flags.GetBool("force") + if err != nil { + return fmt.Errorf("flags parse force bool err: %w", err) + } + c.options.Mockgen, err = flags.GetBool("mock") + if err != nil { + return fmt.Errorf("flags parse mock bool err: %w", err) + } + c.options.PerMethod, err = flags.GetBool("split-by-method") + if err != nil { + return fmt.Errorf("flags parse split-by-method bool err: %w", err) + } + c.options.Domain, err = flags.GetString("domain") + if err != nil { + return fmt.Errorf("flags parse domain string err: %w", err) + } + c.options.GroupName, err = flags.GetString("groupname") + if err != nil { + return fmt.Errorf("flags parse groupname string err: %w", err) + } + c.options.VersionSuffix, err = flags.GetString("versionsuffix") + if err != nil { + return fmt.Errorf("flags parse versionsuffix string err: %w", err) + } + return nil +} + +// parseSwaggerOptions parses the swagger options from the command line flags. +// It parses various string and boolean flags related to swagger options. +func (c *Create) parseSwaggerOptions(flags *pflag.FlagSet) error { + var err error + c.options.SwaggerOn, err = flags.GetBool("swagger") + if err != nil { + return fmt.Errorf("flags parse swagger bool err: %w", err) + } + c.options.SwaggerOut, err = flags.GetString("swagger-out") + if err != nil { + return fmt.Errorf("flags parse swagger-out string err: %w", err) + } + c.options.SwaggerOptJSONParam, err = flags.GetBool("swagger-json-param") + if err != nil { + return fmt.Errorf("flags parse swagger-json-param bool err: %w", err) + } + return nil +} + +// parseProtocolOptions parses the protocol options from the command line flags. +// It parses various string flags related to protocol options. +func (c *Create) parseProtocolOptions(flags *pflag.FlagSet) error { + var err error + c.options.Protocol, err = flags.GetString("protocol") + if err != nil { + return fmt.Errorf("flags parse protocol string err: %w", err) + } + c.options.OtherType, err = flags.GetString("non-protocol-type") + if err != nil { + return fmt.Errorf("flags parse non-protocol-type string err: %w", err) + } + return nil +} + +// parsePBIDLOptions parses the protobuf IDL options from the command line flags. +// It parses various string flags and an array of strings related to protobuf options. +func (c *Create) parsePBIDLOptions(flags *pflag.FlagSet) error { + dirs, err := flags.GetStringArray("protodir") + if err != nil { + return fmt.Errorf("flags get protodir string array failed err: %w", err) + } + c.options.Protodirs = fs.UniqFilePath(dirs) + c.options.Protofile, err = flags.GetString("protofile") + if err != nil { + return fmt.Errorf("flags get protofile string failed err: %w", err) + } + c.options.Gotag, err = flags.GetBool("gotag") + if err != nil { + return fmt.Errorf("flags get gotag bool failed err: %w", err) + } + c.options.IDLType = config.IDLTypeProtobuf + return nil +} + +// parseFBIDLOptions parses the FlatBuffers IDL options from the command line flags. +// It parses various string flags and an array of strings related to FlatBuffers options. +func (c *Create) parseFBIDLOptions(flags *pflag.FlagSet) error { + dirs, err := flags.GetStringArray("fbsdir") + if err != nil { + return fmt.Errorf("flags get fbsdir string array failed err: %w", err) + } + c.options.Protodirs = fs.UniqFilePath(dirs) + c.options.Protofile, err = flags.GetString("fbs") + if err != nil { + return fmt.Errorf("flags get fbs string failed err: %w", err) + } + c.options.IDLType = config.IDLTypeFlatBuffers + return nil +} + +// parseSyncGitOptions parses the synchronization and git options from the command line flags. +// It parses various string and boolean flags related to git synchronization options. +func (c *Create) parseSyncGitOptions(flags *pflag.FlagSet) error { + sync, err := flags.GetBool("sync") + if err != nil { + return fmt.Errorf("flags get git sync bool failed err: %w", err) + } + c.options.Sync = sync + remote, err := flags.GetString("remote") + if err != nil { + return fmt.Errorf("flags get git remote address url failed err: %w", err) + } + c.options.Remote = remote + newTag, err := flags.GetBool("newtag") + if err != nil { + return fmt.Errorf("flags get git new tag bool failed err: %w", err) + } + c.options.NewTag = newTag + tag, err := flags.GetString("tag") + if err != nil { + return fmt.Errorf("flags get git tag failed err: %w", err) + } + c.options.Tag = tag + return nil +} diff --git a/cmd/create/post.go b/cmd/create/post.go new file mode 100644 index 0000000..221cbde --- /dev/null +++ b/cmd/create/post.go @@ -0,0 +1,54 @@ +package create + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + + "trpc.group/trpc-go/trpc-cmdline/plugin" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// PostRunE provides *cobra.Command.PostRunE. +func (c *Create) PostRunE(cmd *cobra.Command, args []string) error { + wd, _ := os.Getwd() + defer os.Chdir(wd) + + var allp []plugin.Plugin + allp = append(allp, plugin.Plugins...) + allp = append(allp, plugin.PluginsExt[c.options.Language]...) + + err := os.Chdir(c.options.OutputDir) + if err != nil { + return err + } + for _, p := range allp { + if !p.Check(c.fileDescriptor, c.options) { + continue + } + + err = p.Run(c.fileDescriptor, c.options) + if err != nil { + return fmt.Errorf( + "running plugin `%s`, err: %w", + p.Name(), err) + } + if c.options.Verbose { + log.Info( + "running plugin %s`%s`%s, err: %v", + log.ColorRed, + p.Name(), + log.ColorGreen, + err) + } + } + + log.Info( + "Create tRPC project %s`%s`%s post process: succeed! (〃'▽'〃)", + log.ColorRed, + fs.BaseNameWithoutExt(c.fileDescriptor.FilePath), + log.ColorGreen) + return nil +} diff --git a/cmd/create/rpcstub.go b/cmd/create/rpcstub.go new file mode 100644 index 0000000..73eadab --- /dev/null +++ b/cmd/create/rpcstub.go @@ -0,0 +1,56 @@ +package create + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "time" + + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/tpl" + "trpc.group/trpc-go/trpc-cmdline/util/fs" +) + +func (c *Create) createRPCOnlyStub() error { + fd, options, outputDir := c.fileDescriptor, c.options, c.options.OutputDir + // In case where the current output directory is not empty, + // generate all the files inside a temporary directory. + // Then move them into the expected output directory. + tmpDir := filepath.Join(outputDir, fmt.Sprintf("tmp-%d", time.Now().UnixNano())) + if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil { + return fmt.Errorf("os.MkdirAll inside create rpc only stub %w", err) + } + defer os.RemoveAll(tmpDir) + // The format of pkg is like: "trpc.group/testapp/testserver". + pkg, err := parser.GetPackage(fd, options.Language) + if err != nil { + return fmt.Errorf("parser get package inside create rpc stub err: %w", err) + } + // Traverse each file in install/asset_${lang}. + if len(fd.Services) != 0 { + if err := tpl.GenerateFiles(fd, tmpDir, options); err != nil { + return fmt.Errorf("generate files from template inside create rpc stub err: %w", err) + } + } + + // Generate IDL stub code for protobuf/flatbuffers. + if err := c.generateIDLStub(tmpDir); err != nil { + return fmt.Errorf("generate rpc stub from template inside create rpc stub err: %w", err) + } + savedir := filepath.Join(tmpDir, "stub", pkg) + saveFiles, err := os.ReadDir(savedir) + if err != nil { + return err + } + for _, f := range saveFiles { + if strings.HasSuffix(f.Name(), "proto") { + continue + } + if options.NoGoMod && f.Name() == "go.mod" { + continue + } + fs.Move(filepath.Join(savedir, f.Name()), outputDir) + } + return nil +} diff --git a/cmd/internal/test_helper.go b/cmd/internal/test_helper.go new file mode 100644 index 0000000..cc0a495 --- /dev/null +++ b/cmd/internal/test_helper.go @@ -0,0 +1,83 @@ +// Package internal provides internal utilities for command to use. +package internal + +import ( + "fmt" + "io" + "math/rand" + "os" + "path/filepath" + + "github.com/spf13/cobra" +) + +// RunAndWatch runs the command. +// It is used only in tests. +// The return string is the stdout/err of the executed command. +func RunAndWatch(cmd *cobra.Command, flags map[string]string, args []string) (string, error) { + tmpd := filepath.Join(os.TempDir(), "trpc") + tmpf := filepath.Join(tmpd, fmt.Sprintf("cmd_output-%d", rand.Uint64())) + + if err := os.MkdirAll(tmpd, os.ModePerm); err != nil { + return "", fmt.Errorf("make dir %s err: %w", tmpd, err) + } + defer os.RemoveAll(tmpd) + + f, err := os.OpenFile(tmpf, os.O_CREATE|os.O_RDWR, os.ModePerm) + if err != nil { + return "", fmt.Errorf("open file %s err: %w", tmpf, err) + } + defer f.Close() + + // Redirect output and error. + sout := os.Stdout + serr := os.Stderr + + os.Stdout = f + os.Stderr = f + defer func() { + os.Stdout = sout + os.Stderr = serr + }() + + for k, v := range flags { + cmd.Flags().Set(k, v) + } + + // PreRun. + if cmd.PreRunE != nil { + if err := cmd.PreRunE(cmd, args); err != nil { + return "", err + } + } else if cmd.PreRun != nil { + cmd.PreRun(cmd, args) + } + + // Run. + if cmd.RunE != nil { + if err := cmd.RunE(cmd, args); err != nil { + return "", err + } + } else if cmd.Run != nil { + cmd.Run(cmd, args) + } + + // PostRun. + if cmd.PostRunE != nil { + if err := cmd.PostRunE(cmd, args); err != nil { + return "", err + } + } else if cmd.PostRun != nil { + cmd.PostRun(cmd, args) + } + + _, err = f.Seek(0, io.SeekStart) + if err != nil { + return "", fmt.Errorf("seek %s to start err: %w", tmpf, err) + } + b, err := io.ReadAll(f) + if err != nil { + return "", fmt.Errorf("read file %s err: %w", tmpf, err) + } + return string(b), nil +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..8cc6a3b --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,98 @@ +// Package cmd provides commands to help developer generating project, testing, etc. +package cmd + +import ( + "fmt" + "path/filepath" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "trpc.group/trpc-go/trpc-cmdline/cmd/apidocs" + "trpc.group/trpc-go/trpc-cmdline/cmd/completion" + "trpc.group/trpc-go/trpc-cmdline/cmd/create" + "trpc.group/trpc-go/trpc-cmdline/cmd/setup" + "trpc.group/trpc-go/trpc-cmdline/cmd/version" + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Printf(`Execution err: + %+v +Please run "trpc -h" or "trpc create -h" (or "trpc {some-other-subcommand} -h") for help messages. +`, err) + } +} + +var ( + cfgFile string + verboseFlag bool +) + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "trpc", + Short: "trpc is an efficiency tool for convenient trpc service development", + Long: `trpc is an efficiency tool for convenient trpc service development. + +For example: +- Generate a complete project or corresponding RPC stub by specifying the pb file +- Send RPC test requests to the target service + +Try using trpc framework + trpc tool to write your next trpc service! +`, + SilenceErrors: true, + SilenceUsage: true, +} + +const defaultConfigFile = "path/to/trpc.yaml" + +func init() { + cobra.OnInitialize(func() { + if err := initConfig(); err != nil { + panic(err) + } + }) + + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", defaultConfigFile, + "Path to the configuration file (automatically calculated)") + rootCmd.PersistentFlags().BoolVarP(&verboseFlag, "verbose", "v", false, "Display detailed log information") + + rootCmd.AddCommand(create.CMD()) + rootCmd.AddCommand(setup.CMD()) + rootCmd.AddCommand(completion.CMD()) + rootCmd.AddCommand(apidocs.CMD()) + rootCmd.AddCommand(version.CMD()) +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() error { + log.SetVerbose(verboseFlag) + + d, err := config.Init() + if err != nil { + return err + } + + if cfgFile == defaultConfigFile { + cfgFile = filepath.Join(d, "trpc.yaml") + } + if cfgFile != "" { + // Use config file from the flag. + log.Debug("using config from %s", cfgFile) + viper.SetConfigFile(cfgFile) + } + + viper.AutomaticEnv() // Read in environment variables that matched. + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err != nil { + return err + } + + return nil +} diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go new file mode 100644 index 0000000..fc03e04 --- /dev/null +++ b/cmd/setup/setup.go @@ -0,0 +1,55 @@ +// Package setup provides setup command. +package setup + +import ( + "fmt" + + "github.com/spf13/cobra" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// CMD returns setup command. +func CMD() *cobra.Command { + setup := func(languages []string) error { + // Load dependencies according to languages specified. + deps, err := config.LoadDependencies(languages...) + if err != nil { + return err + } + // Setup dependencies. + return config.SetupDependencies(deps) + } + setupCmd := &cobra.Command{ + Use: "setup", + Short: "Initialize setup && Install dependency tools", + Long: "Initialize setup && Install dependency tools.", + SilenceErrors: true, + RunE: func(cmd *cobra.Command, _ []string) error { + log.SetPrefix("[setup]") + log.SetVerbose(true) + log.Info("Initializing setup && Installing dependency tools") + lang, err := cmd.Flags().GetStringArray("lang") + if err != nil { + return fmt.Errorf("get lang flag err: %w", err) + } + force, err := cmd.Flags().GetBool("force") + if err != nil { + return fmt.Errorf("get force flag err: %w", err) + } + if _, err := config.Init(config.WithForce(force)); err != nil { + return fmt.Errorf("init config with force=%v, err: %w", force, err) + } + // Do setup according to language. + if err := setup(lang); err != nil { + return fmt.Errorf("setup failed: %v", err) + } + log.Info("Setup completed") + return nil + }, + } + setupCmd.Flags().StringArrayP("lang", "l", nil, "setup tools for languages") + setupCmd.Flags().BoolP("force", "f", false, "force extracting assets to overwrite the existing asset files") + return setupCmd +} diff --git a/cmd/version/version.go b/cmd/version/version.go new file mode 100644 index 0000000..41865b8 --- /dev/null +++ b/cmd/version/version.go @@ -0,0 +1,23 @@ +// Package version provides version command. +package version + +import ( + "fmt" + + "github.com/spf13/cobra" + + "trpc.group/trpc-go/trpc-cmdline/config" +) + +// CMD returns the version command. +func CMD() *cobra.Command { + versionCmd := &cobra.Command{ + Use: "version", + Short: "Show the version of trpc command (commit hash)", + Long: "Show the version of trpc command (commit hash).", + Run: func(_ *cobra.Command, _ []string) { + fmt.Println("trpc-group/trpc-cmdline version:", config.TRPCCliVersion) + }, + } + return versionCmd +} diff --git a/cmd/version/version_test.go b/cmd/version/version_test.go new file mode 100644 index 0000000..d788b3e --- /dev/null +++ b/cmd/version/version_test.go @@ -0,0 +1,25 @@ +package version + +import ( + "strings" + "testing" + + "trpc.group/trpc-go/trpc-cmdline/cmd/internal" + "trpc.group/trpc-go/trpc-cmdline/config" +) + +func TestCmd_Version(t *testing.T) { + if _, err := config.Init(); err != nil { + t.Errorf("config init error: %v", err) + } + + versionCmd := CMD() + output, err := internal.RunAndWatch(versionCmd, nil, nil) + if err != nil { + t.Errorf("versionCmd run and watch error: %v", err) + } + + if !strings.Contains(output, config.TRPCCliVersion) { + t.Errorf("versionCmd.Run() output version mismatch") + } +} diff --git a/config/config.go b/config/config.go new file mode 100755 index 0000000..b589a91 --- /dev/null +++ b/config/config.go @@ -0,0 +1,236 @@ +// Package config provides configuration-related capabilities for this project. +package config + +import ( + "bytes" + "errors" + "fmt" + "math/rand" + "os" + "os/user" + "path/filepath" + "sync" + + "github.com/spf13/viper" + "gopkg.in/yaml.v2" + + "trpc.group/trpc-go/trpc-cmdline/bindata/compress" + "trpc.group/trpc-go/trpc-cmdline/gobin" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// LanguageTemplates is the templates for each programming language. +type LanguageTemplates map[string]*Template + +var once sync.Once +var globalConfig Config + +func init() { + // Auto initialize. + if _, err := Init(); err != nil { + log.Error("init error: %+v", err) + } +} + +type options struct { + force bool +} + +// Option is the option provided for config.Init. +type Option func(*options) + +// WithForce sets whether to force initialize the asset files, i.e. extract the files +// inside the binary to overwrite the existing files located at $HOME/.trpc-cmdline-assets. +// Default is false. +func WithForce(force bool) Option { + return func(o *options) { + o.force = force + } +} + +// Init initializes the configuration. +// If the configuration file trpc.yaml is missing, or the code template is missing, +// or the configuration version does not match, the configuration is automatically installed. +// After the initialization is successful, returns the path of config file's directory. +func Init(opts ...Option) (string, error) { + o := &options{} + for _, opt := range opts { + opt(o) + } + // List of candidate template paths. + paths, err := candidatedInstallPath() + if err != nil { + return "", fmt.Errorf("get Template search path error: %w", err) + } + + // Check if the candidate template path exists. + var reinstall bool + installPath, err := templateInstallPath(paths) + if err != nil { + if err != errTemplateNotFound { + return "", fmt.Errorf("get Template installed path error: %w", err) + } + reinstall = true + installPath = paths[0] + } else { + // Version mismatch, needs to be reinstalled. + dat, err := os.ReadFile(filepath.Join(installPath, "VERSION")) + if err != nil || string(dat) != TRPCCliVersion { + reinstall = true + } + } + // Install the template as needed. + if o.force || reinstall { + if err := installTemplate(installPath); err != nil { + return "", fmt.Errorf("initialize config error: %w", err) + } + } + return installPath, nil +} + +// CurrentTemplatePath gets the installation path of the trpc configuration file, +// which is installed to $HOME/.trpc-cmdline-assets. +func CurrentTemplatePath() (dir string, err error) { + candicates, err := candidatedInstallPath() + if err != nil { + return "", err + } + return templateInstallPath(candicates) +} + +var errTemplateNotFound = errors.New("Template directory not found") + +func candidatedInstallPath() ([]string, error) { + u, err := user.Current() + if err != nil { + return nil, err + } + + candidates := []string{filepath.Join(u.HomeDir, ".trpc-cmdline-assets")} + return candidates, nil +} + +func templateInstallPath(dirs []string) (dir string, err error) { + for _, d := range dirs { + if fin, err := os.Lstat(d); err == nil && fin.IsDir() { + return d, nil + } + } + return "", errTemplateNotFound +} + +func installTemplate(installTo string) error { + tmp := filepath.Join(os.TempDir(), "trpc"+fmt.Sprintf("tmp+%d", rand.Uint64())) + if err := os.RemoveAll(installTo); err != nil { + return fmt.Errorf("remove %s err: %w", installTo, err) + } + if err := os.RemoveAll(tmp); err != nil { + return fmt.Errorf("remove %s err: %w", tmp, err) + } + if err := os.MkdirAll(tmp, os.ModePerm); err != nil { + return fmt.Errorf("mkdir err: %w", err) + } + if err := compress.Untar(tmp, bytes.NewBuffer(gobin.AssetsGo)); err != nil { + return fmt.Errorf("untar to %s err: %w", tmp, err) + } + if err := fs.Move(tmp, installTo); err != nil { + return fmt.Errorf("move %s -> %s err: %w", tmp, installTo, err) + } + if err := os.RemoveAll(tmp); err != nil { + return fmt.Errorf("remove %s after move err: %w", tmp, err) + } + return nil +} + +// GlobalConfig returns global config. +func GlobalConfig() Config { + once.Do(func() { + cfg, err := LoadConfig() + if err != nil { + panic(err) + } + globalConfig = *cfg + }) + return globalConfig +} + +// GetTemplate returns the corresponding configuration information +// based on the given index of the serialization protocol and the language type. +func GetTemplate(idl IDLType, lang string) (*Template, error) { + if !idl.Valid() { + return nil, fmt.Errorf("invalid idltype: %s", idl) + } + + tpl, ok := GlobalConfig().Templates[idl.String()][lang] + if !ok { + return nil, fmt.Errorf("language: %s not supported", lang) + } + return tpl, nil +} + +func repair(cfg *Config) error { + installedPath, err := CurrentTemplatePath() + if err != nil { + return err + } + + for _, tpls := range cfg.Templates { + for lang, tpl := range tpls { + tpl.AssetDir = filepath.Join(installedPath, tpl.AssetDir) + if tpl.Language == "" { + tpl.Language = lang + } + if tpl.LangFileExt == "" { + tpl.LangFileExt = lang + } + } + } + return nil +} + +// LoadConfig loads trpc config. +func LoadConfig() (cfg *Config, err error) { + defer func() { + if err == nil && cfg != nil { + repair(cfg) + } + }() + // Try to load configuration from the file specified by --config flag. + fp := viper.ConfigFileUsed() + if fp != "" { + return loadConfigFile(fp) + } + + // Try to load configuration from the template installation path. + d, err := CurrentTemplatePath() + if err != nil { + return nil, err + } + + fp = filepath.Join(d, "trpc.yaml") + return loadConfigFile(fp) +} + +func loadConfigFile(fp string) (*Config, error) { + b, err := os.ReadFile(fp) + if err != nil { + return nil, err + } + + cfg := Config{} + err = yaml.Unmarshal(b, &cfg) + if err != nil { + return nil, err + } + return &cfg, nil +} + +// UninstallTemplate cleans up installed templates. +func UninstallTemplate() { + user, err := user.Current() + if err != nil { + panic(err) + } + os.RemoveAll(filepath.Join(user.HomeDir, ".trpc-cmdline-assets")) +} diff --git a/config/config_test.go b/config/config_test.go new file mode 100755 index 0000000..fcd6c02 --- /dev/null +++ b/config/config_test.go @@ -0,0 +1,193 @@ +package config + +import ( + "errors" + "os" + "os/user" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/util/fs" +) + +// Backup the current configuration information before running the tests, +// and restore the original configuration information after the tests are complete. +func TestMain(m *testing.M) { + mustBackupTemplate() + ret := m.Run() + mustRestoreTemplate() + os.Exit(ret) +} + +func Test_templateCandidatedPath(t *testing.T) { + t.Run("user: root install for self", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(os.Executable, func() (string, error) { + return "/root/go/bin/trpc", nil + }) + p.ApplyFunc(user.Current, func() (*user.User, error) { + return &user.User{ + Username: "root", + HomeDir: "/root/", + }, nil + }) + defer p.Reset() + + paths, err := candidatedInstallPath() + require.Nil(t, err) + require.Equal(t, []string{"/root/.trpc-cmdline-assets"}, paths) + }) +} + +// Load the trpc.yaml configuration file and return the parsed configuration. +func Test_LoadConfig(t *testing.T) { + t.Run("load config by ~/.trpc-cmdline-assets/trpc.yaml", func(t *testing.T) { + _, err := Init() + require.Nil(t, err) + + c, err := LoadConfig() + require.Nil(t, err) + require.NotZero(t, c) + }) + + t.Run("load config by --config=", func(t *testing.T) { + globalConfig = Config{} + + orig := viper.ConfigFileUsed() + + wd, err := os.Getwd() + if err != nil { + panic(err) + } + src := filepath.Join(filepath.Dir(wd), "install/trpc.yaml") + + defer func() { + viper.Reset() + viper.SetConfigFile(orig) + }() + + viper.SetConfigFile(src) + UninstallTemplate() + + c, err := LoadConfig() + require.Nil(t, err) + require.NotZero(t, c) + }) +} + +// Load the trpc.yaml configuration file and return the parsed configuration. +func Test_CurrentTemplatePath(t *testing.T) { + t.Run("template not installed", func(t *testing.T) { + // Remove all candidate installation paths. + // At this point, the check for the template installation path should return templateNotFound. + UninstallTemplate() + + d, err := CurrentTemplatePath() + require.Equal(t, errTemplateNotFound, err) + require.Zero(t, d) + }) +} + +func Test_Init_Exception(t *testing.T) { + t.Run("templateInstallPath lstat error", func(t *testing.T) { + UninstallTemplate() + p := gomonkey.ApplyFunc(templateInstallPath, func([]string) (string, error) { + return "", errors.New("error != templateNotFound") + }) + _, err := Init() + require.NotNil(t, err) + require.NotEqual(t, err, errTemplateNotFound) + p.Reset() + }) + + t.Run("installTemplate, mkdir error", func(t *testing.T) { + UninstallTemplate() + p := gomonkey.ApplyFunc(os.MkdirAll, func(string, os.FileMode) error { + return errors.New("prevent mkdirall") + }) + _, err := Init() + require.NotNil(t, err) + p.Reset() + }) + + t.Run("initConfig, by ~/.trpc-cmdline-assets/trpc.yaml", func(t *testing.T) { + UninstallTemplate() + p := gomonkey.ApplyFunc(viper.ConfigFileUsed, func() string { + return "" + }) + _, err := Init() + require.Nil(t, err) + p.Reset() + }) +} + +func Test_GetTemplate(t *testing.T) { + _, err := Init() + require.Nil(t, err) + + t.Run("protobuf + go", func(t *testing.T) { + cfg, err := GetTemplate(IDLTypeProtobuf, "go") + require.Nil(t, err) + require.NotNil(t, cfg) + }) + + t.Run("protobuf + aaaaaaa", func(t *testing.T) { + cfg, err := GetTemplate(IDLTypeProtobuf, "aaaaaaa") + require.NotNil(t, err) + require.Nil(t, cfg) + }) + + t.Run("flatbuffers + go", func(t *testing.T) { + fbsCfg, err := GetTemplate(IDLTypeFlatBuffers, "go") + require.Nil(t, err) + // The following content is asserted based on install/trpc.yaml. + require.Contains(t, fbsCfg.AssetDir, "flatbuffers/asset_go") + require.Equal(t, ".tpl", globalConfig.TplFileExt) + require.Equal(t, "go", fbsCfg.LangFileExt) + require.Equal(t, "service_rpc.go.tpl", fbsCfg.RPCServerStub) + require.Equal(t, "service_rpc_test.go.tpl", fbsCfg.RPCServerTestStub) + require.Equal(t, "trpc.group", GlobalConfig().Domain) + }) +} + +func Test_InstallTemplate(t *testing.T) { + dir := filepath.Join(os.TempDir(), "__install_trpc_test") + + os.MkdirAll(dir, os.ModePerm) + defer os.RemoveAll(dir) + + err := installTemplate(dir) + if err != nil { + t.Errorf("install Template error: %v", err) + } +} + +func fileExisted(fp string) bool { + _, err := os.Lstat(fp) + if err != nil { + return false + } + return true +} + +func mustBackupTemplate() { + u, _ := user.Current() + src := filepath.Join(u.HomeDir, ".trpc-cmdline-assets") + dst := filepath.Join(os.TempDir(), "trpc.bak") + + _ = os.RemoveAll(dst) + fs.Copy(src, dst) +} + +func mustRestoreTemplate() { + u, _ := user.Current() + src := filepath.Join(u.HomeDir, ".trpc-cmdline-assets") + dst := filepath.Join(os.TempDir(), "trpc.bak") + + _ = os.RemoveAll(src) + fs.Copy(dst, src) +} diff --git a/config/def.go b/config/def.go new file mode 100644 index 0000000..064f049 --- /dev/null +++ b/config/def.go @@ -0,0 +1,171 @@ +package config + +import ( + "fmt" + "io" + "net/http" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/util/semver" +) + +// IDLType is IDL type. +type IDLType uint + +// Related constants of IDL type. +const ( + IDLTypeProtobuf IDLType = iota // IDL is protobuf + IDLTypeFlatBuffers // IDL is flatbuffers + IDLTypeInvalid +) + +var idlTypeDesc = map[IDLType]string{ + IDLTypeProtobuf: "protobuf", + IDLTypeFlatBuffers: "flatbuffers", +} + +// Valid Check if the IDL type is valid. +func (t IDLType) Valid() bool { + return t < IDLTypeInvalid +} + +// String Return the description of the IDL type. +func (t IDLType) String() string { + if !t.Valid() { + return fmt.Sprintf("unknown type: %d", t) + } + return idlTypeDesc[t] +} + +// Template is language templates. +type Template struct { + Language string `yaml:"language"` // Programming language + LangFileExt string `yaml:"lang_file_ext"` // Source file extension for the programming language + // The output filename for the stub corresponds to: service name + separator + original file name + Separator string `yaml:"separator"` + // Keep the original file name as a suffix for the generated files + KeepOrigName bool `yaml:"keep_orig_name"` + // Follow the camelcase style for generated file names + CamelCaseName bool `yaml:"camelcase_name"` + AssetDir string `yaml:"asset_dir"` // Code template directory + RPCServerStub string `yaml:"rpc_server_stub"` // Server stub + RPCServerTestStub string `yaml:"rpc_server_test_stub"` // Server test stub + RPCClientStub []string `yaml:"rpc_client_stub"` // Client stub + // Whether the client stub includes all service definitions + RPCClientStubPerService bool `yaml:"rpc_client_stub_per_service"` +} + +// OpSys is the system of operation (运营体系). +type OpSys struct { + Name string `yaml:"name"` + Imports []string `yaml:"imports"` +} + +// Config is the global config. +type Config struct { + Domain string `yaml:"domain"` // host in importPath + TplFileExt string `yaml:"tpl_file_ext"` + IDL map[string]*Dependency `yaml:"idl"` // IDL name -> IDL tool + Tools map[string][]*Dependency `yaml:"tools"` // Programming language -> Dependency tools + Plugins map[string][]string `yaml:"plugins"` // Programming language -> Dependency plugins + Templates map[string]map[string]*Template `yaml:"templates"` // idltype -> Code templates for each language +} + +// Dependency is the description of dependencies. +type Dependency struct { + Executable string `yaml:"executable"` // Executable file name. + VersionMin string `yaml:"version_min"` // Min version. + VersionCmd string `yaml:"version_cmd"` // Max version. + ArtifactURL string `yaml:"artifact_url"` // Artifact download URL. + Repository string `yaml:"repository"` // Repository URL. + MD5 string `yaml:"md5"` // md5 sum up. + Fallback string `yaml:"fallback"` // Failure prompt. +} + +// TryInstallTo tries to install the dependency to the given path. +func (d *Dependency) TryInstallTo(path string) error { + rsp, err := http.Get(d.ArtifactURL) + if err != nil { + return fmt.Errorf("install %s from %s err: %w", d.Executable, d.ArtifactURL, err) + } + defer rsp.Body.Close() + if rsp.StatusCode != http.StatusOK { + body, err := io.ReadAll(rsp.Body) + return fmt.Errorf("download from %s, rsp body: %q, body read err: %w", d.ArtifactURL, body, err) + } + dst := filepath.Join(path, d.Executable) + bs, err := io.ReadAll(rsp.Body) + if err != nil { + return fmt.Errorf("read from %s err: %w", d.ArtifactURL, err) + } + if err := os.WriteFile(dst, bs, os.ModePerm); err != nil { + return fmt.Errorf("write to %s err: %w", dst, err) + } + return nil +} + +// Installed checks installed or not. +func (d *Dependency) Installed() bool { + if _, err := exec.LookPath(d.Executable); err != nil { + return false + } + return true +} + +// version returns installed version. +func (d *Dependency) version() (string, error) { + if d.VersionCmd == "" { + return "", nil + } + + cmd := exec.Command("sh", "-c", d.VersionCmd) + if runtime.GOOS == "windows" { + cmd = exec.Command("cmd", "/C", d.VersionCmd) + } + + buf, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("read version failed: %w, command: %s", err, d.VersionCmd) + } + + s := string(buf) + strs := versionRE.FindStringSubmatch(s) + if len(strs) < 2 { + return "", fmt.Errorf("version %s does not match pattern %s", s, versionPattern) + } + version := strings.Join(strs[1:], ".") + return version, nil +} + +// CheckVersion check if installed version meet the version requirement. +func (d *Dependency) CheckVersion() (passed bool, error error) { + // skip checking if cmd/version not specified + if d.VersionMin == "" || d.VersionCmd == "" { + return true, nil + } + + // load version + v, err := d.version() + if err != nil { + return false, err + } + + // compare version and required version + version := v + required := d.VersionMin + + version = versionNumber(version) + required = versionNumber(required) + return semver.NewerThan(version, required), nil +} + +func versionNumber(v string) string { + if len(v) != 0 && (v[0] == 'v' || v[0] == 'V') { + return v[1:] + } + return v +} diff --git a/config/def_test.go b/config/def_test.go new file mode 100644 index 0000000..43e7ec2 --- /dev/null +++ b/config/def_test.go @@ -0,0 +1,21 @@ +package config + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/util/semver" +) + +func TestParseNewProtocVersion(t *testing.T) { + s := versionRE.FindStringSubmatch("22.0") + require.Equal(t, []string{"22.0", "", "22", "0"}, s) + version := versionNumber(strings.Join(s[1:], ".")) + require.Equal(t, ".22.0", version) + major, minor, revision := semver.Versions(version) + require.Equal(t, 22, major) + require.Equal(t, 0, minor) + require.Equal(t, 0, revision) +} diff --git a/config/dependencies.go b/config/dependencies.go new file mode 100644 index 0000000..5b61db9 --- /dev/null +++ b/config/dependencies.go @@ -0,0 +1,101 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "runtime" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +var ( + versionPattern = `[v]?(?:(0|[1-9]\d*)\.)?(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-.*)?` + versionRE = regexp.MustCompile(versionPattern) +) + +// LoadDependencies loads the configuration on demand based on the given language type. +func LoadDependencies(languages ...string) ([]*Dependency, error) { + cfg, err := LoadConfig() + if err != nil { + return nil, err + } + + var deps []*Dependency + depsSet := map[string]*Dependency{} + + deps = append(deps, cfg.IDL[IDLTypeProtobuf.String()]) + deps = append(deps, cfg.IDL[IDLTypeFlatBuffers.String()]) + if len(languages) == 0 { + // Default configures the tools required by all languages. + deps = append(deps, cfg.Tools["go"]...) + } else { + // Configure according to the specified language. + for _, l := range languages { + v, ok := cfg.Tools[l] + if !ok { + continue + } + deps = append(deps, v...) + } + } + for _, v := range deps { + if v == nil { + continue + } + depsSet[v.Executable] = v + } + + deps = []*Dependency{} + for _, v := range depsSet { + if runtime.GOOS == "windows" { + v.ArtifactURL += ".exe" + v.Executable += ".exe" + } + deps = append(deps, v) + } + return deps, nil +} + +// SetupDependencies configures dependency installation. +func SetupDependencies(deps []*Dependency) error { + userHome, err := os.UserHomeDir() + if err != nil { + return fmt.Errorf("get user home dir err for installation: %w", err) + } + path := filepath.Join(userHome, "go", "bin") + for _, dep := range deps { + // Check whether installed, if no, try to install it. + if dep.Installed() { + ok, err := dep.CheckVersion() + if err != nil { + return fmt.Errorf("%s installed, check version, err: %w", dep.Executable, err) + } + if ok { + log.Debug("%s check passed", dep.Executable) + continue + } + log.Debug("%s installed, check version, too old, need reinstall", dep.Executable) + } + log.Debug("%s not installed, need install", dep.Executable) + // Try to install if needed. + if err := dep.TryInstallTo(path); err != nil { + return fmt.Errorf("install %s to %s failed: %w", dep.Executable, path, err) + } + if !dep.Installed() { + log.Error("%s is installed to %s, but it cannot be found, please ensure it is added to your $PATH variable", + dep.Executable, path) + } else { + log.Info("%s is installed to %s", dep.Executable, path) + } + ok, err := dep.CheckVersion() + if err != nil { + return fmt.Errorf("%s is installed, check version err: %w", dep.Executable, err) + } + if !ok { + return fmt.Errorf("%s is still too old, check $PATH, maybe there're several existed", dep.Executable) + } + } + return nil +} diff --git a/config/dependencies_test.go b/config/dependencies_test.go new file mode 100644 index 0000000..516a924 --- /dev/null +++ b/config/dependencies_test.go @@ -0,0 +1,45 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func Test_VersionRE(t *testing.T) { + type arg struct { + ver string + want []string + } + args := []arg{ + { + ver: "0.1.1", + want: []string{"0", "1", "1"}, + }, + { + ver: "1.1.1", + want: []string{"1", "1", "1"}, + }, + { + ver: "10.1.1", + want: []string{"10", "1", "1"}, + }, + { + ver: "v10.1.1", + want: []string{"10", "1", "1"}, + }, + { + ver: "protoc v10.1.1", + want: []string{"10", "1", "1"}, + }, + { + ver: "protoc v10.1.1-beta", + want: []string{"10", "1", "1"}, + }, + } + + for _, a := range args { + vals := versionRE.FindStringSubmatch(a.ver) + require.Equal(t, a.want, vals[1:]) + } +} diff --git a/config/version.go b/config/version.go new file mode 100644 index 0000000..f602323 --- /dev/null +++ b/config/version.go @@ -0,0 +1,4 @@ +package config + +// TRPCCliVersion is the version of trpc-cmdline tool. +var TRPCCliVersion = "v0.0.1" diff --git a/descriptor/desc.go b/descriptor/desc.go new file mode 100755 index 0000000..fd7e402 --- /dev/null +++ b/descriptor/desc.go @@ -0,0 +1,224 @@ +// Package descriptor provides the corresponding capabilities for parsing IDL. +package descriptor + +import ( + "encoding/json" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// Desc provides an abstract interface for the descriptors parsed from IDL. +// Currently, two types of IDLs are supported: protobuf and flatbuffers. +type Desc interface { + // GetName returns the original file name, which may not contain path information or only contain relative paths. + // For example: + // test.pb ./common/test.pb // protobuf + // test.fbs ./common/test.fbs // flatbuffers + GetName() string + // GetFullyQualifiedName has the same function as GetName. + GetFullyQualifiedName() string + // GetPackage returns the defined package name. + // For protobuf, it is the definition corresponding to the package statement. + // For flatbuffers, it is the definition corresponding to the namespace statement. + // For example, + // package trpc.testapp.testserver; // protobuf + // namespace trpc.testapp.testserver; // flatbuffers + GetPackage() string + // GetFileOptions returns the file options defined in the pb file. + // Usually, it will contain the package name information of the language itself. + // For example, + // // File option related to the go package of protobuf. + // option go_package="trpc.group/trpcprotocol/testapp/testserver"; + // // For flatbuffers, the functions that "file option" supported by extend the "attribute". + // attribute "go_package=trpc.group/trpcprotocol/testapp/testserver"; + GetFileOptions() FileOpt + // GetDependencies returns the descriptor of the files that the current IDL depends on. + // For protobuf, it is the files imported by the import statement. + // For flatbuffers, it is the files included by the include statement. + // For example, + // import "common.proto"; // protobuf + // include "common.fbs"; // flatbuffers + GetDependencies() []Desc + // GetServices returns the descriptor of all the RPC services defined in the file. + GetServices() []ServiceDesc + // GetMessageTypes returns the descriptor of all the messages defined in the file. + GetMessageTypes() []MessageDesc +} + +// FileOpt provides an interface for file options. +// "file options" is a term in protobuf. +// This term is kept here for compatibility. +// The corresponding keyword in flatbuffers is "attribute". +// protobuf and flatbuffers have different implementations for this. +type FileOpt interface { + // GetGoPackage returns the value described by the go_package field. + // For example, + // // File option related to the "go package" of protobuf. + // option go_package="trpc.group/trpcprotocol/testapp/testserver"; + // // For flatbuffers, the functions that "file option" supported by extend the "attribute". + // attribute "go_package=trpc.group/trpcprotocol/testapp/testserver"; + GetGoPackage() string +} + +// ServiceDesc provides an interface for describing services for different IDLs. +type ServiceDesc interface { + // GetName returns the name of the RPC service. + GetName() string + // GetMethods returns the descriptor of all the methods defined in this RPC service. + GetMethods() []MethodDesc +} + +// MethodDesc provides an interface for describing methods for different IDLs. +type MethodDesc interface { + // GetName returns the name of the method. + GetName() string + // GetInputType returns the descriptor of the "request" type. + GetInputType() MessageDesc + // GetOutputType returns the descriptor of the "response" type. + GetOutputType() MessageDesc + // IsClientStreaming returns true if it is client streaming. + IsClientStreaming() bool + // IsServerStreaming returns true if it is server streaming. + IsServerStreaming() bool + // GetSourceInfo returns the comment information of this method in the source file. + GetSourceInfo() SourceInfo +} + +// MessageDesc provides an interface for describing messages in different IDLs. +type MessageDesc interface { + // GetFile returns the descriptor of the file in which this message is defined. + GetFile() Desc + // GetFullyQualifiedName returns the full name of this message. + // Usually includes package information, such as "trpc.testapp.testserver.TestMessage". + GetFullyQualifiedName() string +} + +// SourceInfo provides an interface for source code comments in different IDLs. +type SourceInfo interface { + // GetLeadingComments returns the leading comments. + GetLeadingComments() string + // GetTrailingComments returns the trailing comments. + GetTrailingComments() string +} + +// ImportDesc provides an interface for parsing information related to "import" part (currently mainly used for Go). +type ImportDesc struct { + Name string + Path string +} + +// FileDescriptor provides description information for the file scope of an IDL file. +type FileDescriptor struct { + // FD is an interface for IDL, + // such as *FileDescriptor parsed from protobuf and *FbsDescriptor parsed from flatbuffers. + FD Desc + + FilePath string // Absolute path of the current file + RelatvieFilePath string // Relatvie path from current executing directory. + // Extracted from FD, it represents the package name of the IDL (protobuf or flatbuffers), e.g. trpc.$app.$server + PackageName string + // GoPackage is extracted from pb fileOption or fbs attribute, such as "trpc.group/.../helloworld" + GoPackage string + BaseGoPackageName string // BaseGoPackageName is usually the last part of GoPackage. + AppName string // AppName is extracted from PackageName. + ServerName string // ServerName is extracted from PackageName. + // A pb file may import other pb files. + // If there are references in the definition of RPC requests and responses, + // the imported package name corresponding to the type is recorded. + Imports []string + ImportsX []ImportDesc + + FileOptions map[string]interface{} // KV pairs constructed by pb fileOptions or fbs attributes. + Services []*ServiceDescriptor // Supports multiple services, extracted from pb service or fbs rpc_service. + // The package name that let the key is pb file name and let the value is "protoc". + Pb2ValidGoPkg map[string]string + // The importpath in code that let key is pb file name and let value is "go". + Pb2ImportPath map[string]string + // pb file <-> its' deps proto files if any + Pb2DepsPbs map[string][]string + + // The package name that let the key is pb file package directive and let the value is "protoc". + Pkg2ValidGoPkg map[string]string + + // The importpath in code that let key is pb file package directive and let value is "go". + Pkg2ImportPath map[string]string + + // RPCMessageType maps message type names to the filename where defined that type. + RPCMessageType map[string]string // k is pkg.typ defined by pb, v is valid pkg.typ in go. +} + +// Dump prints the protobuf file parsing information. +func (fd *FileDescriptor) Dump() { + log.Debug("************************** FileDescriptor ***********************") + buf, _ := json.MarshalIndent(fd, "", " ") + log.Debug("\n%s", string(buf)) + log.Debug("*****************************************************************") +} + +// ValidateEnabled indicates whether the validate check is enabled or not. +func (fd *FileDescriptor) ValidateEnabled() bool { + for _, k := range fd.Imports { + if strings.Contains(k, "validate.proto") { + return true + } + } + return false +} + +// ServiceDescriptor provides the description information at the service level. +type ServiceDescriptor struct { + Name string // Service name. + RPC []*RPCDescriptor // RPC interface definition. + RPCx []*RPCDescriptor // RPC interface definition, including the RPC alias and original name. +} + +// RPCDescriptor provides the description information at the RPC level. +type RPCDescriptor struct { + Name string // Name of the RPC method. + Cmd string // RPC command word. + // FullyQualifiedCmd is the complete command word used for ServiceDesc and client requests. + FullyQualifiedCmd string + // RPC request message type, including package, such as package_a.TypeA + RequestType string + // RPC response message type, including package name, such as package_b.TypeB + ResponseType string + LeadingComments string // RPC leading comments. + TrailingComments string // RPC trailing comments. + SwaggerInfo SwaggerDescriptor // SwaggerDescriptor is used to generate swagger documentation. + ServerStreaming bool // Used to determine if the RPC method is a server-side streaming. + ClientStreaming bool // Used to determine if it's a client-side streaming. + RequestTypeFileOptions map[string]interface{} + ResponseTypeFileOptions map[string]interface{} + RequestTypePkgDirective string + ResponseTypePkgDirective string + RESTfulAPIInfo RESTfulAPIDescriptor // Used for generating stub code related to RESTful APIs. +} + +// SwaggerDescriptor is the description information required for generating Swagger API documentation. +type SwaggerDescriptor struct { + Title string // RPC method name. + Method string // HTTP's method (if the method supports the HTTP protocol). + Description string // Description of method. + Params map[string]*SwaggerParamDescriptor // Description of the RPC parameters +} + +// SwaggerParamDescriptor is the description information for Swagger parameters. +type SwaggerParamDescriptor struct { + Name string + Required bool + Default string +} + +// RESTfulAPIDescriptor is the description information required for generating stub code for RESTful APIs. +type RESTfulAPIDescriptor struct { + ContentList []*RESTfulAPIContent // RESTful API content. +} + +// RESTfulAPIContent is the content of a RESTful API. +type RESTfulAPIContent struct { + Method string + PathTmpl string + RequestBody string + ResponseBody string +} diff --git a/descriptor/desc_test.go b/descriptor/desc_test.go new file mode 100644 index 0000000..64fa5f9 --- /dev/null +++ b/descriptor/desc_test.go @@ -0,0 +1,93 @@ +package descriptor + +import ( + "log" + "testing" + + "github.com/jhump/protoreflect/desc/protoparse" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/fbs" +) + +func TestFbsDesc(t *testing.T) { + emptySchema := &fbs.SchemaDesc{Name: "empty.fbs"} + reqDesc := &fbs.TableDesc{Name: "HelloRequest"} + rspDesc := &fbs.TableDesc{Name: "HelloResponse"} + methodDesc := &fbs.MethodDesc{Name: "hello", InputTypeDesc: reqDesc, OutputTypeDesc: rspDesc} + rpcDesc := &fbs.RPCDesc{Name: "Service1", Methods: []*fbs.MethodDesc{methodDesc}} + schema := &fbs.SchemaDesc{ + Name: "test1.fbs", + Namespaces: []string{".", "trpc.testapp.testserver"}, + Root: "HelloRequest", + FileExt: "fext", + FileIdent: "fident", + Attrs: []string{"go_package=trpc.group/testapp/testserver"}, + Includes: []string{"test2.fbs"}, + Dependencies: []*fbs.SchemaDesc{emptySchema}, + Tables: []*fbs.TableDesc{reqDesc}, + RPCs: []*fbs.RPCDesc{rpcDesc}, + } + reqDesc.Schema = schema + fbsDesc := &FbsFileDescriptor{FD: schema} + require.Equal(t, "test1.fbs", fbsDesc.GetName()) + require.Equal(t, "test1.fbs", fbsDesc.GetFullyQualifiedName()) + require.Equal(t, "trpc.testapp.testserver", fbsDesc.GetPackage()) + require.Equal(t, NewFbsAttrs(fbsDesc.FD.Attrs), fbsDesc.GetFileOptions()) + require.Equal(t, []Desc{&FbsFileDescriptor{FD: emptySchema}}, fbsDesc.GetDependencies()) + require.Equal(t, []ServiceDesc{&FbsServiceDescriptor{SD: rpcDesc}}, fbsDesc.GetServices()) + require.Equal(t, []MessageDesc{&FbsMessageDescriptor{MD: reqDesc}}, fbsDesc.GetMessageTypes()) + require.Equal(t, "trpc.group/testapp/testserver", fbsDesc.GetFileOptions().GetGoPackage()) + fbsDesc.FD.Attrs = []string{} + require.Equal(t, "", fbsDesc.GetFileOptions().GetGoPackage()) + fbsServiceDesc := &FbsServiceDescriptor{SD: rpcDesc} + require.Equal(t, "Service1", fbsServiceDesc.GetName()) + require.Equal(t, []MethodDesc{&FbsMethodDescriptor{MD: methodDesc}}, fbsServiceDesc.GetMethods()) + fbsMethodDesc := &FbsMethodDescriptor{MD: methodDesc} + require.Equal(t, "hello", fbsMethodDesc.GetName()) + require.Equal(t, &FbsMessageDescriptor{MD: reqDesc}, fbsMethodDesc.GetInputType()) + require.Equal(t, &FbsMessageDescriptor{MD: rspDesc}, fbsMethodDesc.GetOutputType()) + require.False(t, fbsMethodDesc.IsClientStreaming()) + require.False(t, fbsMethodDesc.IsServerStreaming()) + require.Equal(t, &FbsSourceInfo{}, fbsMethodDesc.GetSourceInfo()) + fbsMessageDesc := &FbsMessageDescriptor{MD: reqDesc} + require.Equal(t, &FbsFileDescriptor{FD: schema}, fbsMessageDesc.GetFile()) + require.Equal(t, ".HelloRequest", fbsMessageDesc.GetFullyQualifiedName()) + fbsMessageDesc.MD.Namespace = "trpc.testapp.testserver" + require.Equal(t, ".trpc.testapp.testserver.HelloRequest", fbsMessageDesc.GetFullyQualifiedName()) + fbsSourceInfo := &FbsSourceInfo{} + require.Equal(t, "", fbsSourceInfo.GetLeadingComments()) + require.Equal(t, "", fbsSourceInfo.GetTrailingComments()) +} + +func TestProtoDesc(t *testing.T) { + testpath := "./testcase/" + p := protoparse.Parser{ + ImportPaths: []string{testpath}, + } + fds, err := p.ParseFiles("hello.proto") + require.Nil(t, err) + require.NotNil(t, fds) + fd := fds[0] + require.NotNil(t, fd) + protoFileDesc := &ProtoFileDescriptor{FD: fd} + log.Print(fd) + require.Equal(t, "hello.proto", protoFileDesc.GetName()) + require.Equal(t, "hello.proto", protoFileDesc.GetFullyQualifiedName()) + require.Equal(t, "hello", protoFileDesc.GetPackage()) + require.Equal(t, "trpc.group/examples/hello", protoFileDesc.GetFileOptions().GetGoPackage()) + require.Equal(t, 1, len(protoFileDesc.GetDependencies())) + require.Equal(t, 1, len(protoFileDesc.GetServices())) + require.Equal(t, 1, len(protoFileDesc.GetMessageTypes())) + service := protoFileDesc.GetServices()[0] + require.Equal(t, "hello_svr", service.GetName()) + require.Equal(t, 1, len(service.GetMethods())) + method := service.GetMethods()[0] + require.Equal(t, "Hello", method.GetName()) + require.Equal(t, "message.proto", method.GetInputType().GetFile().GetName()) + require.Equal(t, "message.proto", method.GetOutputType().GetFile().GetName()) + require.False(t, method.IsClientStreaming()) + require.False(t, method.IsServerStreaming()) + require.Equal(t, "", method.GetSourceInfo().GetLeadingComments()) + require.Equal(t, "hello.HelloReq", method.GetInputType().GetFullyQualifiedName()) +} diff --git a/descriptor/fbsdesc.go b/descriptor/fbsdesc.go new file mode 100755 index 0000000..3cedf32 --- /dev/null +++ b/descriptor/fbsdesc.go @@ -0,0 +1,195 @@ +package descriptor + +import ( + "strings" + + "trpc.group/trpc-go/fbs" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// GoPackage is the key's value of "go package" in file options. +const GoPackage = "go_package" + +// FbsFileDescriptor implements the Desc interface and describes all information about a flatbuffers file. +type FbsFileDescriptor struct { + FD *fbs.SchemaDesc +} + +// GetName implements the Desc interface. +func (p *FbsFileDescriptor) GetName() string { + return p.FD.Name +} + +// GetFullyQualifiedName implements the Desc interface. +func (p *FbsFileDescriptor) GetFullyQualifiedName() string { + return p.FD.Name +} + +// GetPackage implements the Desc interface. +func (p *FbsFileDescriptor) GetPackage() string { + // Flatbuffers support multiple namespaces in a single file + // Store each namespace in Namespaces according to the order of appearance + // Here, choose the last appeared namespace as the package name + return p.FD.Namespaces[len(p.FD.Namespaces)-1] +} + +// GetFileOptions implements the Desc interface. +func (p *FbsFileDescriptor) GetFileOptions() FileOpt { + return NewFbsAttrs(p.FD.Attrs) +} + +// GetDependencies implements the Desc interface. +func (p *FbsFileDescriptor) GetDependencies() []Desc { + var descs []Desc + for _, dep := range p.FD.Dependencies { + descs = append(descs, &FbsFileDescriptor{FD: dep}) + } + return descs +} + +// GetServices implements the Desc interface. +func (p *FbsFileDescriptor) GetServices() []ServiceDesc { + var descs []ServiceDesc + for _, sd := range p.FD.RPCs { + descs = append(descs, &FbsServiceDescriptor{SD: sd}) + } + return descs +} + +// GetMessageTypes implements the Desc interface. +func (p *FbsFileDescriptor) GetMessageTypes() []MessageDesc { + var descs []MessageDesc + for _, md := range p.FD.Tables { + descs = append(descs, &FbsMessageDescriptor{MD: md}) + } + return descs +} + +// FbsAttrs implements the FileOpt interface. +// Attrs contains various strings stored in the attribute field of flatbuffers. +// Among them, the following format is customized to provide go package information for flatbuffers files. +// +// attribute "go_package=trpc.group/trpcprotocol/testapp/testserver" +type FbsAttrs struct { + Attrs []string + KV map[string]string + GoPackage *string `protobuf:"bytes,11,opt,name=go_package,json=goPackage" json:"go_package,omitempty"` +} + +// NewFbsAttrs creates a new FbsAttrs object. +// During the creation process, it iterates over the attrs string list to generate key-value pairs. +func NewFbsAttrs(attrs []string) *FbsAttrs { + f := &FbsAttrs{ + Attrs: attrs, + KV: map[string]string{}, + } + for _, kv := range attrs { + strs := strings.Split(kv, "=") + log.Debug("NewFbsAttrs: %v", strs) + if len(strs) == 2 { + f.KV[strs[0]] = strs[1] + } + if strs[0] == GoPackage { + f.GoPackage = &strs[1] + } + log.Debug("KV: %v", f.KV) + } + return f +} + +// GetGoPackage implements the FileOpt interface. +func (f *FbsAttrs) GetGoPackage() string { + if v, ok := f.KV[GoPackage]; ok { + log.Debug("return: %v", v) + return v + } + log.Debug("return empty string") + return "" +} + +// FbsServiceDescriptor implements the ServiceDesc interface. +// Describes all information of an RPC service. +type FbsServiceDescriptor struct { + SD *fbs.RPCDesc +} + +// GetName implements the ServiceDesc interface. +func (p *FbsServiceDescriptor) GetName() string { + return p.SD.Name +} + +// GetMethods implements the ServiceDesc interface. +func (p *FbsServiceDescriptor) GetMethods() []MethodDesc { + var descs []MethodDesc + for _, md := range p.SD.Methods { + descs = append(descs, &FbsMethodDescriptor{MD: md}) + } + return descs +} + +// FbsMethodDescriptor implements the MethodDesc interface. +type FbsMethodDescriptor struct { + MD *fbs.MethodDesc +} + +// GetName implements the MethodDesc interface. +func (p *FbsMethodDescriptor) GetName() string { + return p.MD.Name +} + +// GetInputType implements the MethodDesc interface. +func (p *FbsMethodDescriptor) GetInputType() MessageDesc { + return &FbsMessageDescriptor{MD: p.MD.InputTypeDesc} +} + +// GetOutputType implements the MethodDesc interface. +func (p *FbsMethodDescriptor) GetOutputType() MessageDesc { + return &FbsMessageDescriptor{MD: p.MD.OutputTypeDesc} +} + +// IsClientStreaming implements the MethodDesc interface. +func (p *FbsMethodDescriptor) IsClientStreaming() bool { + return p.MD.ClientStreaming +} + +// IsServerStreaming implements the MethodDesc interface. +func (p *FbsMethodDescriptor) IsServerStreaming() bool { + return p.MD.ServerStreaming +} + +// GetSourceInfo implements the MethodDesc interface. +func (p *FbsMethodDescriptor) GetSourceInfo() SourceInfo { + return &FbsSourceInfo{} +} + +// FbsMessageDescriptor implements the MessageDesc interface. +type FbsMessageDescriptor struct { + MD *fbs.TableDesc +} + +// GetFile implements the MessageDesc interface. +func (p *FbsMessageDescriptor) GetFile() Desc { + return &FbsFileDescriptor{FD: p.MD.Schema} +} + +// GetFullyQualifiedName implements the MessageDesc interface. +func (p *FbsMessageDescriptor) GetFullyQualifiedName() string { + if p.MD.Namespace == "" { + return "." + p.MD.Name + } + return "." + p.MD.Namespace + "." + p.MD.Name +} + +// FbsSourceInfo implements the SourceInfo interface. +type FbsSourceInfo struct{} + +// GetLeadingComments implements the SourceInfo interface. +func (f *FbsSourceInfo) GetLeadingComments() string { + return "" +} + +// GetTrailingComments implements the SourceInfo interface. +func (f *FbsSourceInfo) GetTrailingComments() string { + return "" +} diff --git a/descriptor/protodesc.go b/descriptor/protodesc.go new file mode 100644 index 0000000..7bdfce9 --- /dev/null +++ b/descriptor/protodesc.go @@ -0,0 +1,126 @@ +package descriptor + +import "github.com/jhump/protoreflect/desc" + +// ProtoFileDescriptor implements the Desc interface. +// Describes all information about a protobuf file. +type ProtoFileDescriptor struct { + FD *desc.FileDescriptor +} + +// GetName implements the Desc interface. +func (p *ProtoFileDescriptor) GetName() string { + return p.FD.GetName() +} + +// GetFullyQualifiedName implements the Desc interface. +func (p *ProtoFileDescriptor) GetFullyQualifiedName() string { + return p.FD.GetFullyQualifiedName() +} + +// GetPackage implements the Desc interface. +func (p *ProtoFileDescriptor) GetPackage() string { + return p.FD.GetPackage() +} + +// GetFileOptions implements the Desc interface. +func (p *ProtoFileDescriptor) GetFileOptions() FileOpt { + return p.FD.GetFileOptions() +} + +// GetDependencies implements the Desc interface. +func (p *ProtoFileDescriptor) GetDependencies() []Desc { + var descs []Desc + for _, fd := range p.FD.GetDependencies() { + descs = append(descs, &ProtoFileDescriptor{FD: fd}) + } + return descs +} + +// GetServices implements the Desc interface. +func (p *ProtoFileDescriptor) GetServices() []ServiceDesc { + var descs []ServiceDesc + for _, sd := range p.FD.GetServices() { + descs = append(descs, &ProtoServiceDescriptor{SD: sd}) + } + return descs +} + +// GetMessageTypes implements the Desc interface. +func (p *ProtoFileDescriptor) GetMessageTypes() []MessageDesc { + var descs []MessageDesc + for _, md := range p.FD.GetMessageTypes() { + descs = append(descs, &ProtoMessageDescriptor{MD: md}) + } + return descs +} + +// ProtoServiceDescriptor implements the ServiceDesc interface. +// Describes all information of an RPC service. +type ProtoServiceDescriptor struct { + SD *desc.ServiceDescriptor +} + +// GetName implements the ServiceDesc interface. +func (p *ProtoServiceDescriptor) GetName() string { + return p.SD.GetName() +} + +// GetMethods implements the ServiceDesc interface. +func (p *ProtoServiceDescriptor) GetMethods() []MethodDesc { + var descs []MethodDesc + for _, md := range p.SD.GetMethods() { + descs = append(descs, &ProtoMethodDescriptor{MD: md}) + } + return descs +} + +// ProtoMethodDescriptor implements the MethodDesc interface. +type ProtoMethodDescriptor struct { + MD *desc.MethodDescriptor +} + +// GetName implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) GetName() string { + return p.MD.GetName() +} + +// GetInputType implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) GetInputType() MessageDesc { + return &ProtoMessageDescriptor{MD: p.MD.GetInputType()} +} + +// GetOutputType implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) GetOutputType() MessageDesc { + return &ProtoMessageDescriptor{MD: p.MD.GetOutputType()} +} + +// IsClientStreaming implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) IsClientStreaming() bool { + return p.MD.IsClientStreaming() +} + +// IsServerStreaming implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) IsServerStreaming() bool { + return p.MD.IsServerStreaming() +} + +// GetSourceInfo implements the MethodDesc interface. +func (p *ProtoMethodDescriptor) GetSourceInfo() SourceInfo { + return p.MD.GetSourceInfo() +} + +// ProtoMessageDescriptor implements the MessageDesc interface. +type ProtoMessageDescriptor struct { + MD *desc.MessageDescriptor +} + +// GetFile implements the MessageDesc interface. +func (p *ProtoMessageDescriptor) GetFile() Desc { + return &ProtoFileDescriptor{FD: p.MD.GetFile()} +} + +// GetFullyQualifiedName implements the MessageDesc interface. +func (p *ProtoMessageDescriptor) GetFullyQualifiedName() string { + return p.MD.GetFullyQualifiedName() +} diff --git a/descriptor/testcase/hello.proto b/descriptor/testcase/hello.proto new file mode 100644 index 0000000..d069e70 --- /dev/null +++ b/descriptor/testcase/hello.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello"; + +import "message.proto"; + +message EmptyMessage { +} + +service hello_svr { + rpc Hello (HelloReq) returns (HelloRsp); +} diff --git a/descriptor/testcase/message.proto b/descriptor/testcase/message.proto new file mode 100644 index 0000000..fbf5f65 --- /dev/null +++ b/descriptor/testcase/message.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello"; + +message HelloReq { +} + +message HelloRsp { +} \ No newline at end of file diff --git "a/docs/1-\350\256\276\350\256\241\345\256\236\347\216\260.md" "b/docs/1-\350\256\276\350\256\241\345\256\236\347\216\260.md" new file mode 100644 index 0000000..d954e98 --- /dev/null +++ "b/docs/1-\350\256\276\350\256\241\345\256\236\347\216\260.md" @@ -0,0 +1,12 @@ +# 实现相关 + +## trpc \ +### 使用 "Google Protobuf" 作为 IDL + +***Google Protobuf*** 是 Google 开发的具备自描述能力的一种消息格式,与语言无关、平台无关、协议可扩展,应用比较广泛。为了叙述方便,以下简称 pb。 + +pb 自身具备的一些特性,使他非常适合用作 IDL (Interface Descriptor Language) 用来指导一些代码生成相关的工作,Google 专门开发了一个针对 pb 的编译器`protoc`,它能够解析 pb 文件,并生成与之相关的代码。 + +两年前,我写过一篇文章详细介绍了 `protoc` 及其插件 (如 `protoc-gen-go`) 之间是如何协作用来生成代码的,如果你对此感兴趣可以读一下这篇文章:[Protoc 及其插件工作原理分析](http://km.oa.com/articles/show/324347)。 + +由于 pb 语法简单,可读性强,可以较为完整描述一个微服务所需的元信息,`trpc` 也使用 pb 文件作为 IDL,用来指导服务代码、rpc client stub,甚至是启动配置文件等的生成工作,能一定程度上够简化前期工程搭建的工作。 diff --git "a/docs/2-\344\273\243\347\240\201\346\250\241\346\235\277.md" "b/docs/2-\344\273\243\347\240\201\346\250\241\346\235\277.md" new file mode 100644 index 0000000..281a7fe --- /dev/null +++ "b/docs/2-\344\273\243\347\240\201\346\250\241\346\235\277.md" @@ -0,0 +1,47 @@ +# 如何自定义服务模板文件? + +trpc 使用了 go template,如果您想自定义模板,请先了解下 go template 的使用方式,可以参考 [go template 文档](https://golang.org/pkg/text/template/)。 + +1. 前面已经提到 `asset_${lang}` 下面的模板文件可以任意添加、删除、修改,trpc 会遍历目录下每个 file entry 并处理 + - 如果 file entry 是一个目录,在输出文件中创建该目录 + - 如果 file entry 是一个模板文件,执行 go 模板引擎处理,并在输出文件夹中创建该文件,保留原有的相对路径 + +2. go 模板文件中可以使用的一些模板参数信息 + + 导出给 go 模板引擎的顶层对象是`FileDescriptor`,结合下面的定义您可以访问 pb 文件中定义的内容。如可以在模板文件中通过`{{.PackageName}}`来引用`FileDescriptor.PackageName`的值,go template 非常简单、灵活,您可以详细阅读相关参考手册,也可以参考已经提供的代码模板`install/asset_go/`来学习如何使用。 + + ```go + // FileDescriptor 文件作用域相关的描述信息 + type FileDescriptor struct { + PackageName string // pb 包名称 + Imports []string // 跟 pb 文件中 import 对应的 golang import 路径 + FileOptions map[string]interface{} // fileoptions + Services []*ServiceDescriptor // 支持多 service + } + + // ServiceDescriptor service 作用域相关的描述信息 + type ServiceDescriptor struct { + Name string // 服务名称 + RPC []*RPCDescriptor // rpc 接口定义 + } + + // RPCDescriptor rpc 作用域相关的描述信息 + // + // RequestType 由于涉及到 + type RPCDescriptor struct { + Name string // RPC 方法名 + Cmd string // RPC 命令字 + FullyQualifiedCmd string // 完整的 RPC 命令字,用于 ServiceDesc、client 请求时命令字 + RequestType string // RPC 请求消息类型,包含 package,比如 package_a.TypeA + ResponseType string // RPC 响应消息类型,包含 package,比如 package_b.TypeB + LeadingComments string // RPC 前置注释信息 + TrailingComments string // RPC 后置注释信息 + } + ``` + +3. 也提供了常用的 funcmap 函数,供模板中使用 + - title: `{{hello | title}}` ==> `Hello` + - simplify: `{{simplify helloworld.GreeterServer helloworld}}` ==> `GreeterServer` + - splitList `{{splitList "$" "hello$world"}}` ==> `[hello world]` + - last `{{last (splitList "/" "git.woa.com/abc/def")}}` ==> `def` + - ... diff --git "a/docs/3-\344\275\277\347\224\250\347\244\272\344\276\213.md" "b/docs/3-\344\275\277\347\224\250\347\244\272\344\276\213.md" new file mode 100644 index 0000000..267282d --- /dev/null +++ "b/docs/3-\344\275\277\347\224\250\347\244\272\344\276\213.md" @@ -0,0 +1,43 @@ +README +============================================================================== + +examples 下面提供了一些 trpc 的使用示例,该 readme 提供了一个列表: + +## example-1 生成工程及桩代码 + +- 1 个 pb 文件创建工程 +- 多个 pb 文件创建工程 +- 指定工程 go module +- 指定输出工程文件名 +- 只生成 rpc 桩代码 + +## example-2 使用 pb option 扩展 + +- pb option 扩展信息 +- 为 pb service.rpc 别名 +- 为 pb message.field 添加校验规则 +- 为 pb message.field 添加自定义 tag + +## example-3 文档相关 + +- 生成 swagger 文档 +- 生成 openapi 文档 + +## example-4 模板相关 + +- 自定义代码模板 +- 使用多套代码模板 + +## example-5 rpc 测试相关 + +- trpc rpc... + +## example-6 issue 相关 + +- 快速打开项目 issue 地址 +- 终端直接编辑 issue 并提交 + +## example-7 其他 + +- 问题定位 + diff --git a/docs/4-flatbuffers.md b/docs/4-flatbuffers.md new file mode 100644 index 0000000..41ef2df --- /dev/null +++ b/docs/4-flatbuffers.md @@ -0,0 +1,211 @@ +## 使用 trpc 工具生成 flatbuffers 桩代码 + +### 环境配置 + +用 `trpc` 工具创建 trpc-go flatbuffers 工程需要用到 `flatc` 工具,即 flatbuffers 官方提供的编译器 + +当前依赖的 flatbuffers 为 `v2.0.0`,官方 release 页面提供了编译好的二进制下载,但是在机器上可能会由于动态链接库的缺失而无法使用,这时我们需要从源码编译出 `flatc` 工具 + +首先得到相应版本的仓库: + +```shell +$ git clone -b v2.0.0 --depth=1 https://github.com/google/flatbuffers.git +``` + +然后进行编译 + +```shell +$ cd flatbuffers +$ # 如果没有 cmake 的话可以通过 yum install cmake -y 来安装 +$ cmake . +$ make -j 16 # 设置为 cpu 的核数来加快编译速度 +$ make install # 头文件以及编译好的二进制文件就会被安装到 /usr/local 的相关目录下 +``` + +__注:__ 假如在 make 步骤时因为 `-Werror=shadow` 而报错,可以将 `CMakeLists.txt` 中的这部分去掉,示例操作如下: + +```shell +$ sed -i "s/-Werror=shadow//g" CMakeLists.txt +$ cmake . && make -j 16 && make install # 然后再运行 cmake 和 make 等 +``` + +可以查看 `flatc` 自带的命令行选项说明: + +```shell +$ flatc --help +``` + +### 快速上手 + +类似使用 protobuf 的方式,先写好你的 flatbuffers 对应的 `.fbs` 文件,然后运行 `trpc` 工具来生成相应的桩代码 + +`testcase/flatbuffers/` 目录下面提供了一系列的例子,里面既包含给定的 `.fbs` 文件,还包含了其相应的 `.proto` 文件,这样可以方便大家进行对照比较。除此之外还提供了使用这些文件生成桩代码的脚本 `testcase/flatbuffers/run*.sh`,可以查看脚本内容进行学习。注意这些脚本需要在 `trpc-cmdline` 文件夹下执行 + + +首先看 `greeter.fbs`,这是一个简单但又相当全面的测试文件,里面包含了两个 service 的定义,每个 service 又有四种类型:1. 一发一收 2. 客户端流式 3. 服务端流式 4. 双向流式 + +类似于 protobuf 中的 `option go_package`,flatbuffers 中通过添加一个 attribute 来支持这一功能,如: + +``` +attribute "go_package=trpc.group/trpcprotocol/testapp/greeter"; +``` + +在 `trpc-cmdline` 目录下执行 `./testcase/flatbuffers/rungreeter.sh` 即可生成该文件的桩代码,或者可以直接把脚本中的命令拿出来跑: + +```shell +$ trpc create --fbs testcase/flatbuffers/greeter.fbs -o out-greeter --mod trpc.group/testapp/testgreeter +``` + +其中 `--fbs` 指定了 flatbuffers 的文件名(带相对路径),`-o` 指定了输出路径,`--mod` 指定了生成文件 `go.mod` 中 `package` 的内容,假如没有 `--mod` 的话,它会寻找当前目录下的 `go.mod` 文件,以该文件中的 `package` 内容作为 `--mod` 的内容 + +生成的代码目录结构如下: + +```shell +├── cmd/client/main.go # 客户端代码 +├── go.mod +├── go.sum +├── greeter_2.go # 第二个 service 的服务端实现 +├── greeter_2_test.go # 第二个 service 的服务端测试 +├── greeter.go # 第一个 service 的服务端实现 +├── greeter_test.go # 第一个 service 的服务端测试 +├── main.go # 服务启动代码 +├── stub/trpc.group/trpcprotocol/testapp/greeter # 桩代码文件 +└── trpc_go.yaml # 配置文件 +``` + +在一个终端内,编译并运行服务端: + +```shell +$ go build # 编译 +$ ./testgreeter # 运行 +``` + +在另一个终端内,运行客户端: + +```shell +$ go run cmd/client/main.go +``` + +然后可以在两个终端的 log 中查看相互发送的消息 + +如果想要在 service 中实现一些自己的业务逻辑,可以查看相应 service 中 method 的实现,查看注释中提供的示例来熟悉 flatbuffers 消息的构建方式,比如查看 `cmd/client/main.go` 来了解客户端如何构建一个 flatbuffers 的消息来发送给服务端: + +```go +func callGreeterSayHello() { + proxy := fb.NewGreeterClientProxy( + client.WithTarget("ip://127.0.0.1:8000"), + client.WithProtocol("trpc"), + ) + ctx := trpc.BackgroundContext() + // 一发一收 client 用法示例 + b := flatbuffers.NewBuilder(0) + // 添加字段示例 + // 将 CreateString 中的 String 替换为你想要操作的字段类型 + // 将 AddMessage 中的 Message 替换为你想要操作的字段名 + // i := b.CreateString("GreeterSayHello") + fb.HelloRequestStart(b) + // fb.HelloRequestAddMessage(b, i) + b.Finish(fb.HelloRequestEnd(b)) + reply, err := proxy.SayHello(ctx, b) + if err != nil { + log.Fatalf("err: %v", err) + } + // 将 Message 替换为你需要访问的字段名 + // log.Debugf("simple rpc receive: %q", reply.Message()) + log.Debugf("simple rpc receive: %v", reply) +} +``` + +一般流程如下: + +```go +// 导入桩代码的 package +import fb "trpc.group/trpcprotocol/testapp/greeter" +// 首先创建一个 *flatbuffers.Builder +// 其参数为底层 buffer 的初始大小 +// 一般默认为 1024 +b := flatbuffers.NewBuilder(1024) +// 想要为结构体填充字段的话 +// 首先创建一个该字段类型的对象 +// 比如想要填充的字段类型为 String +// 就可以调用 b.CreateString("a string") 来创建这个字符串 +// 该方法返回的是在 flatbuffer 中的 index +i := b.CreateString("GreeterSayHello") +// 想要构造一个 HelloRequest 结构体 +// 需要调用桩代码中提供的 XXXXStart 方法 +// 表示该结构体构造的开始 +// 其相对应的结束为 fb.HelloRequestEnd +fb.HelloRequestStart(b) +// 该填充字段的名字为 message +// 就可以调用 fb.HelloRequestAddMessage(b, i) +// 通过传入 builder 以及之前构造的字符串的 index 来构造这个 message 字段 +// 其他字段可以通过这种方式不断进行构造 +fb.HelloRequestAddMessage(b, i) +// 当结构体构造结束时调用 XXXEnd 方法 +// 该方法会返回这个结构体在 flatbuffer 中的 index +// 然后调用 b.Finish 可以结束这个 flatbuffer 的构造 +b.Finish(fb.HelloRequestEnd(b)) +``` + +flatbuffers 在发消息的时候是 `flatbuffers.Builder`,序列化时调用 `Marshal` 是直接将其中的 `[]byte` 拿了出来,反序列化时调用 `Unmarshal` 则是从这个 `[]byte` 中构建出原本的结构体,所以服务端在收到消息时得到的直接是该结构体,比如可以查看 `greeter.go` 文件里面 `SayHello` 的实现: + +```go +func (s *greeterServiceImpl) SayHello(ctx context.Context, req *fb.HelloRequest, b *flatbuffers.Builder) error { + // 单发单收 flatbuffers 处理逻辑(仅供参考,请根据需要修改) + log.Debugf("Simple server receive %v", req) + // 将 Message 替换为你想要操作的字段名 + v := req.Message() // Get Message field of request. + var m string + if v == nil { + m = "Unknown" + } else { + m = string(v) + } + // 添加字段示例 + // 将 CreateString 中的 String 替换为你想要操作的字段类型 + // 将 AddMessage 中的 Message 替换为你想要操作的字段名 + idx := b.CreateString("welcome " + m) // 创建一个 flatbuffers 中的字符串 + fb.HelloReplyStart(b) + fb.HelloReplyAddMessage(b, idx) + b.Finish(fb.HelloReplyEnd(b)) + return nil +} +``` + +想要访问收到消息中的字段时,直接如下访问即可: + +```go +req.Message() // 访问 req 中的 message 字段 +``` + +更多用法可以查看生成文件中的示例以及 `testcase/flatbuffers/` 下面各种其他的测试用例,各测试用例简要特点概括如下: + +* 1-without-import: RPC 方法需要的结构体定义都放在一个文件中,没有 include 其他文件,这是最简单的情况 + +* 2-multi-fb-same-namespace: 在同一目录下有多个 `.fbs` 文件,每个 `.fbs` 文件的 `namespace` 都是一样的(flatbuffers 中的 `namespace` 等同于 protobuf 中的 `package` 语句),然后其中一个主文件 include 了其他 `.fbs` 文件 + +* 3-multi-fb-diff-namespace: 在同一个目录下有多个 `.fbs` 文件,每个 `.fbs` 文件的 `namespace` 不一样,比如定义 RPC 的主文件中引用了不同 `namespace` 中的类型 + +* 4.1-multi-fb-same-namespace-diff-dir: 多个 `.fbs` 文件的 `namespace` 相同,但是在不同的目录下,主文件 `helloworld.fbs` 中在 include 其他文件时使用相对路径,可以看下 `run4.1.sh`,其中并不需要用 `--fbsdir` 来指定搜索路径 + +* 4.2-multi-fb-same-namespace-diff-dir: 除了 `helloworld.fbs` 文件中 include 语句里面只使用文件名以外,其余和 4.1 完全相同,这个例子想要正确运行,需要添加 `--fbsdir` 来指定搜索路径,见 `run4.2.sh`: +```shell +trpc create --fbsdir testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/request \ + --fbsdir testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/response \ + --fbs testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/helloworld.fbs \ + -o out-4-2 \ + --mod trpc.group/testapp/testserver42 +``` +所以为了尽可能简化命令行参数,建议在 include 语句时写上文件的相对路径(如果不在一个文件夹中的话) + +* 5-multi-fb-diff-gopkg: 多个 `.fbs` 文件,多文件之间有 include 关系,他们的 `go_package` 不相同。注意:由于 `flatc` 的限制,目前不支持两个文件在 `namespace` 相同的情况下 `go_package` 却不同,并要求一个文件中的 `namespace` 和 `go_package` 的最后一段必须相同(比如 `trpc.testapp.testserver` 和 `trpc.group/testapp/testserver` 最后一段 `testserver` 是相同的) + +### 实现细节 + +1. 添加了 `--fbs` 标志,用于指定 flatbuffers 的文件路径 +2. 添加了 `--fbsdir` 标志,用于指定 include 文件的搜索路径 +3. 添加对 `.fbs` 文件的解析,解析操作由 `https://trpc.group/trpc-go/fbs` 完成,见 `parser/parser.go` +4. `descriptor.FileDescriptor` 中的 `FD` 字段提为 `interface`,分成了 protobuf 以及 flatbuffers 两种不同的实现,分别放在 `descriptor/protodesc.go` 以及 `descriptor/fbsdesc.go` 中 +5. 为 flatbuffers 添加自己的模板文件,放在了 `install/flatbuffers` 目录下,protobuf 相关的模板文件移动到了 `install/protobuf` 目录下,相应修改了配置文件 `install/trpc.yaml` 以及 `config.go` 中的定义 +6. 添加对 `flatc` 调用的封装,见 `util/fb/`,相关使用见 `create.go` +7. 添加了各种 testcase 以及相关运行脚本,见 `testcase/flatbuffers/`,测试代码见 `create_test.go` 中的 `TestCreateCmdByFlatbuffers` diff --git a/docs/examples/example-1/README.md b/docs/examples/example-1/README.md new file mode 100644 index 0000000..b2251b7 --- /dev/null +++ b/docs/examples/example-1/README.md @@ -0,0 +1,161 @@ +example-1 工程创建 +============================================================================== + +# 选项介绍 + +这里介绍下如何使用 trpc 命令来创建工程,首先查看下`trpc create`创建工程时的常用选项。可以看到有非常多的选项,不要被吓到,绝大多数情况下`trpc create -p `就足够了。 + +```bash +$ trpc help create +指定 pb 文件快速创建工程或 rpcstub, + +'trpc create' 有两种模式: +- 生成一个完整的服务工程 +- 生成被调服务的 rpcstub,需指定'--rpconly'选项。 + +Usage: + trpc create [flags] + +Flags: + --alias rpcname 采用别名模式 + --assetdir string 允许自定义模板 & 指定模板路径 + -f, --force 强制覆盖已经存在的代码 + --gotag 生成自定义 pb struct tag (default true) + -h, --help help for create + --mock go generate 生成 mock 桩代码(工程下可运行 go generate 更新) (default true) + -m, --mod string 指定 go module, 默认生成 module 名为:trpc.app.${pb.package} + --openapi 生成 openapi 3.0 文档 + -o, --output string 指定输出目录(生成完整工程默认输出到名为 pb 文件的目录,rpconly 默认当前目录 + --protocol string 指定使用的协议类型,支持:trpc, http, etc (default "trpc") + -d, --protodir stringArray pb 文件(含依赖 pb 文件)的搜索路径,允许指定多次 (default [.]) + -p, --protofile string 指定服务对应的 pb 文件 + --rpconly 只生成桩代码(建议在 stub 目录下执行),可以配合-o 使用 + -s, --split-by-method 是否支持按方法分文件 + --swagger 生成 swagger api 文档 + --swagger-json-param 生成 swagger api 文档请求参数,使用 json body + --swagger-out string 生成 swagger api 文档 (default "apidocs.swagger.json") + -v, --verbose 显示详细日志信息 +``` + +# 1 个 pb 文件创建工程 + +推荐使用 pb 文件作为 IDL 来描述服务接口,这个对公司内同学特别是后台同学来说,应该不陌生。 + +一个服务的 pb 文件通常包含了 service 定义,rpc 定义,message 定义等,我们先来看一个 pb 文件就可以描述完整服务接口的情形,这种最简单。 + +file: hello.proto + +``` +syntax = "proto3"; +package hello; + +option go_package="trpc.group/anygroup/protocols/hello"; + +// hello request +message Req{} + +// hello response +message Rsp{} + +// hello service +service hello_service { + // Hello method + rpc Hello(Req) returns(Rsp); +} +``` + +执行 trpc 命令创建工程: + +```bash +$ trpc create -p hello.proto +[create] 创建 trpc 工程 ```hello``` 代码生成成功 +[create] 创建 trpc 工程 ```hello``` 后处理成功 +``` + +trpc 命令生成了一个完整的工程,默认输出都和 pb 文件同名的目录中,生成的目录结构如下所示。 + +- main.go 是服务入口; +- hello_service.go 是服务接口实现,对应单元测试文件也已生成; +- stub 下面是 pb 文件对应的桩代码部分,包括*.pb.go、*.trpc.go、*.mock.go; +- 注意查看下 go.mod 中的 module,一般是按照 trpc.app.$service 来进行命名的; + +```bash +hello +├── go.mod +├── go.sum +├── hello_service.go +├── hello_service_test.go +├── main.go +├── stub +│   └── trpc.group +│   └── anygroup +│   └── protocols +│   └── hello +│   ├── go.mod +│   ├── hello.pb.go +│   ├── hello.proto +│   ├── hello.trpc.go +│   └── hello_service_mock.go +└── trpc_go.yaml +``` + +现在可以直接在工程下面进行编译构建`go build`或者测试`go test`。 + +# 多个 pb 文件创建工程 + +多个 pb 文件创建工程的情景,指的是我们描述服务接口的 pb 文件中,通过 import 引入了外部其他 pb 文件,并引用了其中的一些定义。 + +这里的情况根据 pb 目录的组织情况,可以很简单,也可以很复杂: + +- 服务 pb 文件,与引入的 pb 文件是否 package 相同; +- 服务 pb 文件,与引入的 pb 文件是否在同一个目录; +- 服务 pb 文件,引入 pb 文件时,是否添加了虚拟路径; +- 被引入的的 pb 文件中,是否又引入了其他的 pb 文件,上面 3 点问题进一步假如问题域; +- ... + +对 pb 不熟悉的同学,会想当然认为 pb 很简单嘛,那是因为不了解,pb 作为一个自描述的消息格式,其必须要提供严谨一致的解析才能保证后续消息的正确性。 + +这里的问题不是很想展开多说,要穷尽大家的使用场景也非常耗费篇幅和时间,如果您对这方面感兴趣,可以参考下 create_test.go 中 create 命令字的测试用例。 + +我们只描述下相对来说比较简单的情况: +- 服务 pb 为 hello.proto,其中引入了一个外部的 pb 文件 world.proto; +- 它们可能 package 相同,也可能不同; +- 它们可能在相同目录,也可能在不同目录; + +anyway,我们需要关注几个点,也只想让开发者关注这几个点: +- 服务 pb 是谁,`-p ` 来指定 +- 被引入的 pb 从哪里可以找到,`-d ` 来指定,可以多次指定该选项以允许从多个路径中搜索; + +所以最终的命令大致这样就可以了:`trpc create -p protofile -d dir1 -d dir2`。 + +见识过很多 pb 应用比较混乱的案例,这种情况下,我的建议是: +- 简化你的 pb 组织方式,这很重要; +- 编写好构建脚本,如 build.sh,在里面使用 trpc 命令,并写好路径搜索参数,方便后续使用; + +其他更好的方法,还是优先考虑简化协议组织方式吧,没有什么比这个更高效的。 + +# 指定工程 go module + +指定工程 go module 的方式有多种: +- 您可以先执行 `go mod init ` 初始化之后,然后在当前目录执行`trpc create`,此时将直接在当前目录生成工程文件; +- 您也可以什么都不指定,直接 `trpc create`,将使用 pb 文件名作为输出目录名,对应 go module 将使用 trpc.app.$service 或 package(注:会调整); +- 您也可以显示指定,直接 `trpc create -mod ` 在创建时指定 go module 名称; + +以上 3 种方式都可以使用,开发人员可以根据自己习惯来选择。 + +# 指定工程生成目录 + +指定工程生成目录,有三种方式: +- 如果您已经初始化过 go module,那么将直接将当前目录作为输出目录; +- 如果执行`trpc create`时没有显示指定输出目录,将默认使用 pb 文件名作为输出目录; +- 如果执行`trpc create`时通过选项`--output|-o`显示指定了输出目录,则使用指定的目录; + +以上 3 种方式都可以使用,开发人员可以根据自己习惯来选择。 + +# 只生成 rpc 桩代码 + +有时我们并不需要根据 pb 创建一个完整的工程,比如当我们希望调用一个下游服务,我们现在获得了其 pb 文件,现在如果能生成其 rpc 桩代码在项目中引用,我们调用起来就方便多了,怎么办呢? + +执行命令 `trpc create -p --rpconly` 即可,--rpconly 选项会控制只生成 rpc 对应的桩代码,其他的一概不生成,输出目录默认是当前目录。 + +您也可以通过选项 `--output|-o`来控制桩代码的输出路径。 diff --git a/docs/examples/example-1/demo/Makefile b/docs/examples/example-1/demo/Makefile new file mode 100644 index 0000000..4e6c69f --- /dev/null +++ b/docs/examples/example-1/demo/Makefile @@ -0,0 +1,9 @@ +all: + trpc create --protofile=greeter.proto -v + #trpc create --protofile=greeter.proto -v -rpconly + +.PHONY: clean + +clean: + rm -rf greeter + diff --git a/docs/examples/example-1/demo/greeter.proto b/docs/examples/example-1/demo/greeter.proto new file mode 100644 index 0000000..32683a2 --- /dev/null +++ b/docs/examples/example-1/demo/greeter.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package trpc.greeter; + +option go_package="trpc.group/trpc.app/trpc.greeter"; + +import "helloworld/helloworld.proto"; + +// HelloReq say hello request +message HelloReq { + string msg = 1; + helloworld.Love love = 2; +} + +// HelloRsp say hello response +message HelloRsp { + uint32 err_code = 1; + string err_msg = 2; +} + +// ByeReq say bye request +message ByeReq { + string msg = 1; + helloworld.Hate hate = 2; +} + +// ByeRsp say bye response +message ByeRsp { + uint32 err_code = 1; + string err_msg = 2; +} + +// greeter say hello and say bye +service greeter { + + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp); // @alias=/greeter.greeter/Hello + + // Bye say bye + rpc Bye(ByeReq) returns(ByeRsp); // @alias=/greeter.greeter/Bye + + // Test Import ByeReq,Love + rpc TestImportV1(ByeReq) returns(helloworld.Love); // @alias=/greeter.greeter/testimport1 + + // Test Import Hate,Love + rpc TestImportV2(helloworld.Hate) returns(helloworld.Love); // @alias=/greeter.greeter/testimport2 +} + diff --git a/docs/examples/example-1/demo/helloworld/go.mod b/docs/examples/example-1/demo/helloworld/go.mod new file mode 100644 index 0000000..9aebbee --- /dev/null +++ b/docs/examples/example-1/demo/helloworld/go.mod @@ -0,0 +1,8 @@ +module helloworld2019 + +go 1.12 + +require ( + github.com/golang/protobuf v1.4.3 + google.golang.org/protobuf v1.25.0 +) diff --git a/docs/examples/example-1/demo/helloworld/go.sum b/docs/examples/example-1/demo/helloworld/go.sum new file mode 100644 index 0000000..2384568 --- /dev/null +++ b/docs/examples/example-1/demo/helloworld/go.sum @@ -0,0 +1,67 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/docs/examples/example-1/demo/helloworld/helloworld.pb.go b/docs/examples/example-1/demo/helloworld/helloworld.pb.go new file mode 100644 index 0000000..fe04e02 --- /dev/null +++ b/docs/examples/example-1/demo/helloworld/helloworld.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.12.4 +// source: helloworld.proto + +package helloworld2019 + +import ( + reflect "reflect" + sync "sync" + + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type Love struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Love) Reset() { + *x = Love{} + if protoimpl.UnsafeEnabled { + mi := &file_helloworld_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Love) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Love) ProtoMessage() {} + +func (x *Love) ProtoReflect() protoreflect.Message { + mi := &file_helloworld_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Love.ProtoReflect.Descriptor instead. +func (*Love) Descriptor() ([]byte, []int) { + return file_helloworld_proto_rawDescGZIP(), []int{0} +} + +type Hate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Hate) Reset() { + *x = Hate{} + if protoimpl.UnsafeEnabled { + mi := &file_helloworld_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Hate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Hate) ProtoMessage() {} + +func (x *Hate) ProtoReflect() protoreflect.Message { + mi := &file_helloworld_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Hate.ProtoReflect.Descriptor instead. +func (*Hate) Descriptor() ([]byte, []int) { + return file_helloworld_proto_rawDescGZIP(), []int{1} +} + +var File_helloworld_proto protoreflect.FileDescriptor + +var file_helloworld_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x06, + 0x0a, 0x04, 0x4c, 0x6f, 0x76, 0x65, 0x22, 0x06, 0x0a, 0x04, 0x48, 0x61, 0x74, 0x65, 0x42, 0x10, + 0x5a, 0x0e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x32, 0x30, 0x31, 0x39, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_helloworld_proto_rawDescOnce sync.Once + file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc +) + +func file_helloworld_proto_rawDescGZIP() []byte { + file_helloworld_proto_rawDescOnce.Do(func() { + file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData) + }) + return file_helloworld_proto_rawDescData +} + +var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_helloworld_proto_goTypes = []interface{}{ + (*Love)(nil), // 0: helloworld.Love + (*Hate)(nil), // 1: helloworld.Hate +} +var file_helloworld_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_helloworld_proto_init() } +func file_helloworld_proto_init() { + if File_helloworld_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Love); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Hate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_helloworld_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_helloworld_proto_goTypes, + DependencyIndexes: file_helloworld_proto_depIdxs, + MessageInfos: file_helloworld_proto_msgTypes, + }.Build() + File_helloworld_proto = out.File + file_helloworld_proto_rawDesc = nil + file_helloworld_proto_goTypes = nil + file_helloworld_proto_depIdxs = nil +} diff --git a/docs/examples/example-1/demo/helloworld/helloworld.proto b/docs/examples/example-1/demo/helloworld/helloworld.proto new file mode 100644 index 0000000..d802c5c --- /dev/null +++ b/docs/examples/example-1/demo/helloworld/helloworld.proto @@ -0,0 +1,7 @@ +syntax = "proto3"; +package helloworld; + +option go_package = "helloworld2019"; + +message Love{} +message Hate{} diff --git a/docs/examples/example-2/README.md b/docs/examples/example-2/README.md new file mode 100644 index 0000000..17b4912 --- /dev/null +++ b/docs/examples/example-2/README.md @@ -0,0 +1,136 @@ +README +============================================================================== + +为了支持更多的应用场景,trpc 也在`trpc-go/trpc`自定义了一些 pb 扩展,用来支持: + +# 1. 支持接口别名 trpc.alias + +## pb 的写法 + +- 在 `rpc` 的 `body` 中定义 `option`,形如 + +```protobuf +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { option(trpc.alias) = "/api/v1/helloworld"; }; +} +``` + +这种方式适用于需要对接口进行重命名的操作,比如一个 trpc 接口的 rpcName 通常是 +/package.service/method 这种形式的,如果想提供一个 http 接口的话可能根据 api 网关配 +置要求需要配置成符合指定样式的,如/api/service/method。 + +pb 大致就按照方式进行编写,如果是因为存量协议问题,如 ilive 协议中只有数值型大写、小写命令字: + +``` +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { option (trpc.alias) = "0x100_0x200";}; +} +``` + +再或者,为了兼容存量协议,有些协议头设计是没有字符串形式的 cmd 或者 method 字段的, +可能只有一个数值型的 cmd 字段,这种就需要将字符串形式的 rpcName 转换成对应数值的字 +符串形式,以方便后续编码时将其转换成数值设置到协议头。 + +对应协议的 Encode 函数会将其 split 为大小写命令字并分别设置到协议头字段中去。 + +- `trpc.alias` 重命名 `rpc` 的方法名 + +```protobuf +service helloworld_svr { + //@alias= "/api/helloworld" + rpc Hello(HelloReq) returns(HelloRsp); +} +``` + +## 使用方法 + +1. pb 中加入 `option` 定义,或者使用 @alias 注解,推荐使用前者,注解的方式后续会移除。 +2. 运行命令的时候: + +```bash +# option 的方式 +trpc create -p=./cmd/testcase.option/helloworld.proto + +# 注解的方式 +trpc create -p=./cmd/testcase.option/helloworld.proto --alias +``` + +引用这里的扩展选项,需要引入 trpc.proto,在 trpc 安装阶段该 pb 文件会自动安装到 ~/.trpc-cmdline-assets/ 下面, + +上述 ~/.trpc-cmdline-assets 搜索路径会自动设置到 pb 的搜索路径中,以保证能够正确解析。 + +执行命令 `trpc create -p hello.proto` 来完成工程的创建,如果您是使用的//@alias +来指定别名,则需要显示指定--alias 选项。 + +ps: + +建议使用 option 的方式,因为下面你会看到 swagger、gotag 都是 option 方式,希望保持一致的操作风格。 +后续也不排除会 drop --alias 这个选项以及//@alias 注解的方式。 + +# 2. 支持自定义 struct tag trpc.go_tag + +## pb 的写法 + +```pb +import "trpc/proto/trpc_options.proto"; + +message Req{ + string msg = 1 [ (trpc.go_tag)='gorm:"any_msg"' ]; +} +``` + +## 使用方法 + +运行命令: + +```bash +trpc create -p=./cmd/testcase.option/helloworld.swagger.proto --go_tag +``` + +# 3. 支持 swagger api 文档,比较多,略 + +## pb 的写法 + +- 在 `rpc` 的 `body` 中定义 option,形如 + +```protobuf +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.swagger) = { + title : "你好世界" + method: "get" + description: + "入参:msg\n" + "作用:用于演示 helloword\n" + params: { + name: "msg" + required: true + default: "hello" + } + params: { + name: "cnt" + required: true + default: "1" + } + }; + }; +} +``` + +- `trpc.swagger` 的 `title` 为该 `rpc` 的方法名,`method` 为 `http` 的请求方法(如果该接口用于 `http`, + 由于 `swagger-ui` 会识别一个 `method`,如果该字段不填,默认为 `post`),`description` 用于描述此接口。 +- `params` 则用于指定 `request` 各字段的一些属性,比如是否为必要字段 (`required`), 默认值 (`default`), `params` 可以写多次从而描述多个字段。 +- 假如期望生成的 swagger 描述的 "parameters" 显示为 `"in": "body"`, 需要额外指定 `--swagger-json-param` 标志 (`--swagger` 标志仍需要提供)。 + +## 使用方法 + +运行命令: + +```bash +trpc create -p=./cmd/testcase.option/helloworld.swagger.proto --swagger --alias +``` + +- 在当前目录下会生成 `apidocs.swagger.json` +- 下载 `swagger-ui` (https://github.com/swagger-api/swagger-ui) +- 进入到仓库下的 `dist` 目录,将 `apidocs.swagger.json` 拷贝至此,并修改 `index.html` 文件中的 `url` 为 `apidocs.swagger.json`。 +- `npm install -g http-server`,直接运行 `http-server` 后可以通过 bash 显示的 url 对 swagger 页面进行访问。 diff --git a/docs/examples/example-2/README.short.md b/docs/examples/example-2/README.short.md new file mode 100644 index 0000000..6c0946e --- /dev/null +++ b/docs/examples/example-2/README.short.md @@ -0,0 +1,94 @@ +# `rpc option` 测试用例 + +## option alias + +### pb 的写法 + +- 在 `rpc` 的 `body` 中定义 `option`,形如 + +```protobuf +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.alias) = "/api/v1/helloworld"; + }; +} +``` + +- `trpc.alias` 重命名 `rpc` 的方法名。 + +```protobuf +service helloworld_svr { + //@alias= "/api/helloworld" + rpc Hello(HelloReq) returns(HelloRsp); +} +``` + + +### 使用方法 + +1. pb 中加入 `option` 定义,或者使用 @alias 注解,推荐使用前者,注解的方式后续会移除。 +2. 运行命令的时候: + +```bash +# option的方式 +trpc create -p=./cmd/testcase.option/helloworld.proto + +# 注解的方式 +trpc create -p=./cmd/testcase.option/helloworld.proto --alias +``` + +## option swagger + +### pb 的写法 + +- 在 `rpc` 的 `body` 中定义 option,形如 + +```go +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.swagger) = { + title : "你好世界" + method: "get" + description: + "入参:msg\n" + "作用:用于演示 helloword\n" + }; + }; +} +``` + +- `trpc.swagger` 的 `title` 为该 `rpc` 的方法名,`method` 为 `http` 的请求方法(如果该接口用于 `http`, +由于 `swagger-ui` 会识别一个 `method`,如果该字段不填,默认为 `post`),`description` 用于描述此接口。 + +### 使用方法 + +运行命令: + +```bash +trpc create -p=./cmd/testcase.option/helloworld.swagger.proto --swagger --alias +``` + +- 在当前目录下会生成 `apidocs.swagger.json` +- 下载 `swagger-ui` (https://github.com/swagger-api/swagger-ui) +- 进入到仓库下的 `dist` 目录,将 `apidocs.swagger.json` 拷贝至此,并修改 `index.html` 文件中的 `url` 为 `apidocs.swagger.json`。 +- `npm install -g http-server`,直接运行 `http-server` 后可以通过 bash 显示的 url 对 swagger 页面进行访问。 + +## option go_tag + +### pb 的写法 + +```pb +import "trpc/proto/trpc_options.proto"; + +message Req{ + string msg = 1 [ (trpc.go_tag)='gorm:"any_msg"' ]; +} +``` + +### 使用方法 + +运行命令: + +```bash +trpc create -p=./cmd/testcase.option/helloworld.swagger.proto --go_tag +``` diff --git a/docs/examples/example-2/demo-alias1-v2/helloworld.proto b/docs/examples/example-2/demo-alias1-v2/helloworld.proto new file mode 100644 index 0000000..f38cd2c --- /dev/null +++ b/docs/examples/example-2/demo-alias1-v2/helloworld.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +import "trpc/v2/proto/trpc_options.proto"; +package app.helloworld; + +option go_package = "trpc.group/trp.app/app.helloworld"; + +// Hello +message HelloRequest { + string from = 1; // say hello from + string to = 2; // say hello to + string words = 3; // hello words +} + +message HelloResponse { + uint32 err_code = 1; // error code + string err_msg = 2; // error msg +} + +// Bye +message ByeRequest { + string from = 1; // say bye from + string to = 2; // say bye to + string words = 3; // bye words +} + +message ByeResponse { + uint32 err_code = 1; // error code + string err_msg = 2; // error msg +} + +// service: greeter +service greeter { + rpc SayHello(HelloRequest) returns(HelloResponse) { + option (trpc.v2.alias) = "/rpc/app.helloworld.SayHello"; + } + rpc SayBye(ByeRequest) returns(ByeResponse) { + option (trpc.v2.alias) = "/rpc/app.helloworld.SayBye"; + }; +} + + diff --git a/docs/examples/example-2/demo-alias1/Makefile b/docs/examples/example-2/demo-alias1/Makefile new file mode 100644 index 0000000..c48455a --- /dev/null +++ b/docs/examples/example-2/demo-alias1/Makefile @@ -0,0 +1,14 @@ +all: + @echo "------------- [trpc create] --------------" + trpc create --protofile=helloworld.proto -protocol=trpc + +.PHONY: clean + +clean: + rm -rf greeter + +compile: + @echo "------------- [compile trpc] -------------" + cd ../../../trpc-cmdline/ + make clean && make && make install + @cd - diff --git a/docs/examples/example-2/demo-alias1/README.md b/docs/examples/example-2/demo-alias1/README.md new file mode 100644 index 0000000..a2198fa --- /dev/null +++ b/docs/examples/example-2/demo-alias1/README.md @@ -0,0 +1,128 @@ +# generate *.pb.go + +生成 ****.pb.go*** 的做法,通过大家习惯的方式,直接借助 ***protoc*** 命令来生成: +```bash +protoc --go_out=. helloworld.proto +``` + +# generate server stub + +通过 jhump/protoreflect 来解析 *.proto 文件,解析后得到 ***FileDescriptorProto*** 对象,该对象中记录了我们关心的 *.proto 描述信息,然后将这些信息填充到模板中,完成 server、client stub 的代码生成。 + +对于 server stub,这里需要注意与框架代码的整合: +- 一方面要符合业务开发人员的习惯,使业务开发工作尽可能简单,如只填充业务函数即可; +- 一方面要将业务代码和框架代码进行粘合,组合框架能力、默认插件实现、整合 wrapper 方法等实现开箱即用; + +server 要处理的请求命令字或者 rpc 接口,都已经在*.proto 中定义: +- `trpc` 根据 service 中定义的 rpc,建立映射关系 rpcName->Handler; +- `trpc` 提供方法,使得 server 能够注册上述映射关系,并在 router 中根据 req 找到 Handler; + +可以参考 `protoc --go_out=plugins=grpc:.` 与 `protoc --go_out=.` 两种方式生成的代码的区别,来参考下 grpc 是如何建立映射关系的。 + +## demo + +```protobuf +syntax = "proto3"; +package helloworld; + +// Hello +message HelloRequest { + string from = 1; // say hello from + string to = 2; // say hello to + string words = 3; // hello words +} + +message HelloResponse { + uint32 errcode = 1; // error code + string errmsg = 2; // error msg +} + +// Bye +message ByeRequest { + string from = 1; // say bye from + string to = 2; // say bye to + string words = 3; // bye words +} + +message ByeResponse { + uint32 errcode = 1; // error code + string errmsg = 2; // error msg +} + +// service: greeter +service greeter { + rpc SayHello ( HelloRequest ) returns ( HelloResponse ); + rpc SayBye ( ByeRequest ) returns ( ByeResponse ); +} +``` + +运行 trpc 来生成 server 工程:`trpc create -protofile=helloworld.proto -protocol=trpc`,需要生成的内容应该包括: + +- helloworld.pb.go +- service interface + +```go +import pb "helloworld.proto" + +type GreeterServer interface { + SayHello(ctx context.Context, req *pb.HelloRequest) (rsp *pb.HelloResponse, error) + SayBye(ctx context.Context, req *pb.ByeRequest) (rsp *pb.ByeResponse, error) +} +``` + +- service rpcName->rpcMethod register + +```go +func RegisterGreeterServer(s *server.Server, svr GreeterServer) { + s.RegisterService(&_Greeter_serviceDesc, svr) +} + +func _Greeter_SayHello_Handler(svr interface{}, ctx context.Context) error { + reqCtx := ctx.Value(ctxkey) + + req := new(HelloRequest) + if err := reqCtx.Decode(req); err != nil { + return err + } + + if rsp, err := svr.SayHello(ctx, req); err != nil { + return err + } + + reqCtx.rspChan <- rsp + return nil +} + +var _Greeter_serviceDesc = trpc.ServiceDesc{ + ServiceName: "helloworld.greeter", + HandlerType: (*GreeterServer)(nil), + Methods: []trpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: _Greeter_SayHello_Handler, + }, + { + MethodName: "SayBye", + Handler: _Greeter_SayBye_Handler, + } + }, + Streams: []trpc.StreamDesc{}, + MetaData: "helloworld.proto", +} + +``` + +当前 server 端提供了一个 server.WithHandler(....) 来封装所有的请求处理、tracing、拦截器、监控、logging 等逻辑,这个没问题,Handler 内部会请求 Dispatcher 来完成 rpc 请求到 rpc 处理函数的分发。所以这里还需要提供一个 Dispatcher? + +- 方法 1:trpc 可以显示提供一个 dispatcher 出来,server 端使用的时候 WithDispatcher(GreeterServer.Dispatcher) 就可以; +- 方法 2:新增一个方法 server.RegisterService(trpc.ServiceDesc),server 自己注册; +- 方法 3:Dispatcher 接口提供 Add 等方法,支持直接注册到 dispatcher; +- 方法 4:server 提供 Dispatch(rpcName, rpcMethod) 直接进行注册,内部注册到 server.Opts.Dispatcher 上; + +有多种方式,需要综合考虑下,对于后面支持进程多 server 实例有用处! + +# generate client stub + +# generate config + +# generate others diff --git a/docs/examples/example-2/demo-alias1/helloworld.proto b/docs/examples/example-2/demo-alias1/helloworld.proto new file mode 100644 index 0000000..8113d73 --- /dev/null +++ b/docs/examples/example-2/demo-alias1/helloworld.proto @@ -0,0 +1,41 @@ +syntax = "proto3"; +import "trpc/proto/trpc_options.proto"; +package app.helloworld; + +option go_package = "trpc.group/trp.app/app.helloworld"; + +// Hello +message HelloRequest { + string from = 1; // say hello from + string to = 2; // say hello to + string words = 3; // hello words +} + +message HelloResponse { + uint32 err_code = 1; // error code + string err_msg = 2; // error msg +} + +// Bye +message ByeRequest { + string from = 1; // say bye from + string to = 2; // say bye to + string words = 3; // bye words +} + +message ByeResponse { + uint32 err_code = 1; // error code + string err_msg = 2; // error msg +} + +// service: greeter +service greeter { + rpc SayHello(HelloRequest) returns(HelloResponse) { + option (trpc.alias) = "/rpc/app.helloworld.SayHello"; + } + rpc SayBye(ByeRequest) returns(ByeResponse) { + option (trpc.alias) = "/rpc/app.helloworld.SayBye"; + }; +} + + diff --git a/docs/examples/example-2/demo-alias2/Makefile b/docs/examples/example-2/demo-alias2/Makefile new file mode 100644 index 0000000..113ecd3 --- /dev/null +++ b/docs/examples/example-2/demo-alias2/Makefile @@ -0,0 +1,8 @@ +all: + trpc create --protofile=greeter.proto -v + +.PHONY: clean + +clean: + rm -rf greeter + diff --git a/docs/examples/example-2/demo-alias2/greeter.proto b/docs/examples/example-2/demo-alias2/greeter.proto new file mode 100644 index 0000000..96c84d2 --- /dev/null +++ b/docs/examples/example-2/demo-alias2/greeter.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +package greeter; + +option go_package="trpc.group/trpc.app/greeter"; + +// HelloReq say hello request +message HelloReq { + string msg = 1; +} + +// HelloRsp say hello response +message HelloRsp { + uint32 err_code = 1; + string err_msg = 2; +} + +// greeter say hello and say bye +service greeterxyz { + + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp); // @alias=/greeter.greeter/Hello +} + +service greeterx { + + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp); // @alias=/greeter.greeter/Hello +} diff --git a/docs/examples/example-2/demo-gotag-v2/helloworld.go_tag.proto b/docs/examples/example-2/demo-gotag-v2/helloworld.go_tag.proto new file mode 100644 index 0000000..f2a5b20 --- /dev/null +++ b/docs/examples/example-2/demo-gotag-v2/helloworld.go_tag.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package hello; + +import "trpc/v2/proto/trpc_options.proto"; + +option go_package = "trpc.group/trpc-go/trpc-cmdline/docs/examples/demo-gotagv2"; + +message Req { + string msg = 1 [(trpc.v2.go_tag) = 'gorm:"any_msg"']; +} +message Rsp { +} + +service hello_service { + rpc Hello (Req) returns (Rsp); +} diff --git a/docs/examples/example-2/demo-gotag/helloworld.go_tag.proto b/docs/examples/example-2/demo-gotag/helloworld.go_tag.proto new file mode 100644 index 0000000..05e3802 --- /dev/null +++ b/docs/examples/example-2/demo-gotag/helloworld.go_tag.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package hello; + +import "trpc/proto/trpc_options.proto"; + +option go_package = "trpc.group/trpc-go/trpc-cmdline/docs/examples/demo-gotag"; + +message Req { + string msg = 1 [(trpc.go_tag) = 'gorm:"any_msg"']; +} +message Rsp { +} + +service hello_service { + rpc Hello (Req) returns (Rsp); +} diff --git a/docs/examples/example-2/pboptions/options.proto b/docs/examples/example-2/pboptions/options.proto new file mode 100644 index 0000000..fd39e57 --- /dev/null +++ b/docs/examples/example-2/pboptions/options.proto @@ -0,0 +1,54 @@ +import "google/protobuf/descriptor.proto"; + +extend google.protobuf.FileOptions { + optional string my_file_option = 50000; +} +extend google.protobuf.MessageOptions { + optional int32 my_message_option = 50001; +} +extend google.protobuf.FieldOptions { + optional float my_field_option = 50002; +} +extend google.protobuf.EnumOptions { + optional bool my_enum_option = 50003; +} +extend google.protobuf.EnumValueOptions { + optional uint32 my_enum_value_option = 50004; +} +extend google.protobuf.ServiceOptions { + optional MyEnum my_service_option = 50005; +} +extend google.protobuf.MethodOptions { + optional MyMessage my_method_option = 50006; +} + +option (my_file_option) = "Hello world!"; + +message MyMessage { + option (my_message_option) = 1234; + + optional int32 foo = 1 [(my_field_option) = 4.5]; + optional string bar = 2; +} + +enum MyEnum { + option (my_enum_option) = true; + + FOO = 1 [(my_enum_value_option) = 321]; + BAR = 2; +} + +message RequestType {} +message ResponseType {} + +service MyService { + option (my_service_option) = FOO; + + rpc MyMethod(RequestType) returns(ResponseType) { + // Note: my_method_option has type MyMessage. We can set each field + // within it using a separate "option" line. + option (my_method_option).foo = 567; + option (my_method_option).bar = "Some string"; + } +} + diff --git a/docs/examples/example-3/README.md b/docs/examples/example-3/README.md new file mode 100644 index 0000000..fe866f9 --- /dev/null +++ b/docs/examples/example-3/README.md @@ -0,0 +1,21 @@ +## example-3 文档相关 + +准确地说是 api 文档,在后台同学与 Web 同学或者相互之间沟通服务接口的时候,api 文档非常有帮助。 + +目前支持 swagger 以及 openapi 3.0 规范的 api 文档的生成。 + +为了保持功能的纯粹性,我们将 api 文档生成逻辑移动到了`trpc apidocs`子命令: + +- 生成 swagger 文档,`trpc apidocs -p --swagger`,默认输出到 apidocs.swagger.json +- 生成 openapi 文档,`trpc apidocs -p --openapi`,默认输出到 apidocs.openapi.json + +您也可以指定对应的输出选项来控制输出到的文件,或者控制请求参数的编码方式。 + +关于 swagger、openapi 相关 option 的使用,请参考 example-2 中的说明。 + +当已经生成了 swagger 文档之后,您可以安装 swagger 命令,执行`swagger server apidocs.swagger.json`来查看 api 文档。 +您复制、粘贴到在线的 swagger editor 来查看 api 文档信息。 + +openapi 的使用方式大致与 swagger 类似,只是结构上有点差异。 + + diff --git a/docs/examples/example-3/demo-swagger/Makefile b/docs/examples/example-3/demo-swagger/Makefile new file mode 100644 index 0000000..7a4c123 --- /dev/null +++ b/docs/examples/example-3/demo-swagger/Makefile @@ -0,0 +1,9 @@ +all: + #trpc create --protofile=greeter.proto --swagger + trpc apidocs -p helloworld.swagger.proto --swagger + +.PHONY: clean + +clean: + rm -rf apidocs.swagger.json + diff --git a/docs/examples/example-3/demo-swagger/helloworld.swagger.proto b/docs/examples/example-3/demo-swagger/helloworld.swagger.proto new file mode 100644 index 0000000..c44a011 --- /dev/null +++ b/docs/examples/example-3/demo-swagger/helloworld.swagger.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; +package helloworld; + +import "trpc/proto/trpc_options.proto"; +import "trpc/swagger/swagger.proto"; + +message HelloReq{ + string msg = 1; + int32 cnt = 2; +} +message HelloRsp{ + int32 err_code = 1; + string err_msg = 2; +} + +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.alias) = "/api/v1/helloworld"; + + option(trpc.swagger) = { + title : "你好世界" + method: "get" + description: + "入参:msg\n" + "作用:用于演示 helloword\n" + params: { + name: "msg" + required: true + default: "hello" + } + params: { + name: "cnt" + required: true + default: "1" + } + }; + }; +} diff --git a/docs/examples/example-4/README.md b/docs/examples/example-4/README.md new file mode 100644 index 0000000..59c0858 --- /dev/null +++ b/docs/examples/example-4/README.md @@ -0,0 +1,23 @@ +## example-4 自定义模板 + +### trpc create --assetdir + +trpc 默认提供的代码模板,可能不能满足所有业务要求,如果想自定义代码模板,也是可以的,以 go 工程为例。 + +- 您可以copy/paste ~/.trpc-cmdline-assets/protobuf/asset_go/ 目录到自定义模板目录,如 mygo,然后在里面对模板进行调整、增删等; + - 添加的文件,如果是以\*.tpl 结尾的,则创建工程时会作为模板被处理,反之当做普通文件直接拷贝; + - 添加的目录,创建工程的时候,会保持原目录结构不变,将目录拷贝到生成的工程中; + - 之后创建工程的时候,可以执行命令 `trpc create --assetdir=mygo -p protofile` 来应用模板。 + +注意: +添加目录、模板文件通常不会有问题,如果要调整现有的模板、路径,最好对现在的代码生成工具的逻辑有比较清晰的认识。 +现有的一些逻辑是和目录结构相关的,贸然修改可能会导致生成的工程出问题,如引用关系错误、不能正常编译等。 + +- 如果您想直接修改~/.trpc-cmdline-assets/asset_go 下的模板文件,也是可以的,但是不推荐,原因如下: + - 该工具的优化不仅是代码层面的,也有模板层面的调整,有些情况下工具升级后需要清理旧模板; + - 为了使得工具能够自动清理旧模板,trpc 工具执行时会检查当前版本与机器上的模板版本是否一致,不一致则安装新模板; + +注意: +这意味着,在路径下的~/.trpc-cmdline-assets/asset_go 下的修改可能会被新模板覆盖。所以还是建议如果确实有自定义模板需求,请独立目录维护模板。 + + diff --git a/docs/helloworld/helloworld.proto b/docs/helloworld/helloworld.proto new file mode 100644 index 0000000..80f8855 --- /dev/null +++ b/docs/helloworld/helloworld.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package helloworld; + +option go_package = "github.com/some-repo/examples/helloworld"; + +// HelloRequest is hello request. +message HelloRequest { + string msg = 1; +} + +// HelloResponse is hello response. +message HelloResponse { + string msg = 1; +} + +// HelloWorldService handles hello request and echo message. +service HelloWorldService { + // Hello says hello. + rpc Hello(HelloRequest) returns(HelloResponse); +} diff --git a/go.mod b/go.mod new file mode 100755 index 0000000..12d0268 --- /dev/null +++ b/go.mod @@ -0,0 +1,64 @@ +module trpc.group/trpc-go/trpc-cmdline + +go 1.18 + +require ( + github.com/agiledragon/gomonkey v2.0.2+incompatible + github.com/go-git/go-billy/v5 v5.3.1 + github.com/go-git/go-git/v5 v5.4.2 + github.com/golang/mock v1.6.0 + github.com/hashicorp/go-multierror v1.1.1 + github.com/iancoleman/strcase v0.2.0 + github.com/jhump/protoreflect v1.9.0 + github.com/manifoldco/promptui v0.9.0 + github.com/pkg/errors v0.9.1 + github.com/spf13/cobra v1.5.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.12.0 + github.com/stretchr/testify v1.8.0 + go.uber.org/multierr v1.6.0 + google.golang.org/protobuf v1.31.0 + gopkg.in/yaml.v2 v2.4.0 + trpc.group/trpc-go/fbs v0.0.0-20230817040915-edc204322f88 + trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 +) + +require ( + github.com/Microsoft/go-winio v0.4.16 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/chzyer/readline v1.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emirpasic/gods v1.12.0 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/sergi/go-diff v1.1.0 // indirect + github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/subosito/gotenv v1.4.0 // indirect + github.com/xanzy/ssh-agent v0.3.0 // indirect + go.uber.org/atomic v1.7.0 // indirect + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect + golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect + golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100755 index 0000000..8d1e1a0 --- /dev/null +++ b/go.sum @@ -0,0 +1,633 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= +github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw= +github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= +github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jhump/protoreflect v1.9.0 h1:npqHz788dryJiR/l6K/RUQAyh2SwV91+d1dnh4RjO9w= +github.com/jhump/protoreflect v1.9.0/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= +github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568 h1:iKx0VcikTdB4xj9Ho1Opn9AKzWFknYDE7oW/KBWZf9g= +google.golang.org/genproto v0.0.0-20220713161829-9c7dac0a6568/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +trpc.group/trpc-go/fbs v0.0.0-20230817040915-edc204322f88 h1:d4F12SJF/PsKfih4yn1S+vhnxvfx53J6m+bHnPgPRhE= +trpc.group/trpc-go/fbs v0.0.0-20230817040915-edc204322f88/go.mod h1:qfMELiRmCtn1dru1Sl6+slWkEEhSUncvZEafV1cwchc= +trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952 h1:AhjP72IKa1YKnSIayk1X5xSzKrem0EanjZ7oMc2HYOw= +trpc.group/trpc/trpc-protocol/pb/go/trpc v0.0.0-20230803031059-de4168eb5952/go.mod h1:K+a1K/Gnlcg9BFHWx30vLBIEDhxODhl25gi1JjA54CQ= diff --git a/gobin/assets.go b/gobin/assets.go new file mode 100644 index 0000000..d33a47f --- /dev/null +++ b/gobin/assets.go @@ -0,0 +1,4 @@ +package gobin +var AssetsGo = []uint8{ +31,139,8,0,0,0,0,0,0,255,236,189,123,115,219,56,178,56,186,255,74,159,2,203,201,102,169,140,76,201,206,235,148,50,222,123,242,156,201,61,51,137,127,137,119,247,220,154,154,242,80,36,36,225,103,138,96,64,80,182,87,209,119,191,133,6,64,2,124,72,148,45,219,243,16,107,119,98,145,120,52,26,221,141,70,163,187,241,175,183,159,62,191,255,248,225,47,183,249,12,135,195,225,179,39,79,224,223,225,112,88,254,87,124,253,203,225,147,167,135,195,39,79,159,63,63,60,252,203,240,240,232,240,232,233,95,208,240,86,161,82,79,150,114,159,253,101,56,100,148,242,117,229,54,125,47,15,238,119,242,44,134,222,208,59,188,111,40,246,207,125,61,147,200,231,227,108,50,193,44,29,248,105,138,249,217,148,14,130,121,56,8,34,130,99,62,152,251,36,246,166,212,227,73,116,237,62,214,243,255,225,147,225,211,67,193,255,195,199,71,79,158,63,62,124,254,151,225,209,225,209,179,39,123,254,191,139,39,241,131,115,127,138,145,152,103,212,237,46,151,232,65,72,197,143,15,254,28,163,209,49,242,222,192,79,180,90,117,151,203,3,244,32,197,11,70,2,124,194,40,167,1,141,160,72,254,227,64,151,154,210,147,243,105,222,196,137,236,4,126,235,34,23,132,207,144,247,142,68,248,99,194,9,141,83,111,74,207,52,52,162,16,66,165,150,142,145,151,215,198,113,8,127,147,121,66,25,71,110,183,195,89,18,32,103,185,52,192,95,173,6,226,237,193,148,234,127,157,110,103,83,17,69,248,109,74,70,116,234,116,59,147,49,116,155,195,185,90,137,151,5,91,33,103,74,248,44,27,123,1,157,15,166,148,78,35,60,48,185,110,74,29,212,237,44,151,136,249,241,20,163,7,222,123,24,83,42,48,222,233,44,151,131,71,232,115,130,3,50,185,66,124,134,145,28,49,32,4,95,38,17,9,8,143,174,250,104,66,25,194,151,254,60,137,240,72,149,17,96,89,179,185,90,13,60,207,243,6,41,103,89,192,147,241,139,203,203,75,7,61,26,168,142,16,153,160,128,198,220,39,113,138,60,228,188,112,36,8,226,211,131,133,15,83,237,166,73,68,248,143,36,229,240,221,235,21,69,72,28,226,75,89,240,112,181,18,157,27,111,134,128,21,81,12,71,41,86,149,28,49,147,48,167,250,91,28,194,167,226,207,30,204,182,194,12,180,215,23,36,200,22,36,144,164,245,89,254,157,22,164,151,46,152,24,237,107,127,142,163,215,126,10,197,116,21,15,240,240,21,5,226,99,32,62,234,106,170,139,185,238,99,142,249,140,134,86,221,79,39,175,139,94,88,18,104,242,86,101,155,219,22,133,63,225,47,167,87,137,85,254,19,254,146,225,148,195,107,171,104,154,84,139,166,9,141,83,156,151,85,133,101,163,39,231,211,134,118,79,206,167,111,8,195,1,39,139,18,231,213,20,222,204,139,70,127,117,204,168,128,146,224,87,128,42,70,208,6,170,162,116,11,176,138,30,27,193,34,19,228,226,47,214,16,10,150,237,65,185,78,121,174,142,145,155,48,18,243,9,114,38,99,239,111,169,99,145,191,231,152,133,191,70,126,202,191,226,75,193,120,95,115,18,232,245,10,104,34,69,17,117,221,76,233,36,139,34,46,126,153,95,30,128,124,124,131,211,128,145,132,83,214,219,48,182,2,15,205,99,83,196,213,110,108,178,240,117,198,86,116,83,30,155,250,178,126,108,98,104,147,44,14,80,224,71,209,114,89,97,234,213,106,185,212,60,184,90,185,61,180,236,118,18,70,47,175,4,205,77,198,222,7,124,81,91,235,53,8,247,19,81,210,237,118,58,82,214,123,255,38,124,118,234,179,41,230,174,67,146,209,96,112,120,244,220,3,197,120,180,92,250,97,136,254,107,56,28,42,249,179,90,57,189,190,93,85,47,127,174,88,7,74,235,163,42,222,235,118,2,126,41,128,19,139,135,247,202,15,206,167,140,102,113,248,154,198,28,95,114,183,167,103,210,143,195,156,13,36,180,159,57,195,254,156,196,211,252,189,16,122,152,229,239,5,226,7,3,244,86,138,127,68,39,40,75,69,113,31,141,73,40,25,141,198,126,132,210,188,33,5,124,183,35,95,245,17,102,76,0,7,40,244,44,212,6,252,178,215,237,144,9,20,249,235,49,138,73,36,144,221,137,232,212,123,231,115,63,154,184,14,102,108,132,254,182,112,160,157,94,183,179,234,118,196,122,68,68,147,195,23,136,160,239,208,211,23,136,124,251,45,212,28,195,28,21,43,160,152,172,87,25,137,66,204,92,9,216,187,87,234,247,251,152,112,226,71,159,201,127,112,175,219,41,13,242,101,24,202,81,190,35,56,10,61,249,253,19,78,34,63,192,176,84,58,159,57,35,241,212,65,36,70,175,25,246,57,150,47,164,172,17,37,38,162,38,2,218,188,162,25,186,240,99,142,56,69,23,148,157,67,161,82,163,206,79,56,77,253,41,134,22,95,134,161,250,89,110,47,22,11,193,186,246,72,8,164,48,246,76,168,220,201,156,123,159,37,83,74,74,90,75,243,18,223,164,215,131,165,211,144,26,171,213,103,238,51,238,142,21,198,74,31,11,176,221,113,95,64,34,138,141,189,119,36,38,233,204,45,21,126,27,135,238,24,186,80,4,48,58,86,84,228,125,198,240,237,69,153,46,214,18,134,160,140,85,183,218,216,235,136,166,24,90,172,54,216,130,208,68,49,150,38,253,82,171,159,112,176,112,13,224,143,143,17,161,222,219,143,239,36,160,99,134,253,115,36,129,170,33,240,141,3,169,167,140,38,90,136,49,14,5,45,248,65,128,211,84,17,130,232,226,13,30,103,211,137,235,0,179,34,5,59,98,56,192,100,129,71,232,111,95,156,62,98,105,226,233,89,131,233,104,83,113,33,43,2,154,114,41,77,38,77,210,165,36,69,50,160,108,58,81,178,226,32,37,33,46,36,200,94,116,236,69,199,189,136,142,26,54,7,225,241,50,14,53,187,111,77,112,55,227,227,18,27,75,50,108,199,198,109,234,229,92,92,199,194,235,21,129,156,133,83,40,86,101,225,107,179,211,6,110,186,13,102,218,49,47,9,86,170,97,164,205,204,227,244,186,205,76,179,145,103,122,221,205,12,211,74,176,246,209,248,186,178,21,86,75,156,68,87,215,89,47,127,51,203,165,164,233,6,62,19,163,107,94,48,155,170,46,116,85,107,201,108,98,170,44,246,217,85,161,73,239,121,233,183,200,75,54,157,239,148,149,118,186,106,164,4,8,0,177,36,64,104,35,53,183,169,105,16,179,218,84,175,86,221,149,241,119,241,87,119,48,64,205,36,138,82,204,83,105,122,148,47,81,42,222,130,150,38,95,144,255,8,2,172,167,125,68,99,168,171,151,55,18,98,175,187,240,217,186,14,73,204,213,238,95,116,32,55,247,147,200,159,122,239,99,254,47,159,185,15,155,235,246,145,19,59,125,116,56,60,122,210,71,78,138,185,238,216,52,200,142,101,181,191,167,214,136,156,94,87,27,29,230,62,137,141,110,79,124,150,98,247,119,109,138,20,66,172,173,41,165,150,70,86,247,125,80,177,127,110,229,169,61,255,155,82,111,78,195,27,157,249,153,207,112,56,28,62,127,250,180,233,252,255,232,241,243,231,246,249,223,225,243,195,195,195,253,249,223,93,60,32,65,146,13,103,117,90,102,192,9,144,60,213,41,164,221,176,231,229,133,215,159,31,26,71,131,210,160,47,190,59,206,245,142,4,85,11,235,12,254,248,11,242,190,167,63,209,80,119,50,167,97,22,97,105,130,245,147,196,43,164,97,217,144,173,74,46,151,178,129,146,101,122,74,229,151,127,97,150,18,26,139,87,114,232,44,9,66,194,172,97,9,64,98,108,3,93,124,212,53,142,17,103,100,206,200,116,38,15,214,172,226,101,224,172,122,249,228,149,144,192,148,110,34,133,123,72,216,106,133,142,255,129,188,65,202,179,241,192,120,11,144,171,53,231,188,143,30,44,36,25,140,143,228,57,228,137,207,103,121,175,139,42,160,139,124,148,126,28,34,55,166,28,185,51,63,77,24,158,144,75,228,0,174,57,14,102,214,233,233,96,113,36,170,246,122,168,139,242,167,190,238,148,209,44,177,42,203,154,91,84,148,181,19,101,145,223,170,250,5,137,241,52,163,219,182,96,157,248,70,126,60,29,64,221,113,54,169,27,54,22,136,53,123,13,241,34,197,129,172,19,28,76,113,124,144,226,96,49,88,28,13,22,126,68,66,159,11,101,229,90,45,212,87,47,67,47,15,169,53,200,3,7,61,56,239,193,73,175,65,84,139,50,61,41,66,208,60,98,252,105,112,129,119,250,233,228,117,206,56,130,17,160,213,47,25,97,138,47,171,243,125,32,217,205,170,105,247,165,27,88,123,208,142,22,71,222,208,27,126,75,226,128,206,19,159,147,113,132,187,247,45,126,239,253,169,93,255,119,225,244,99,60,155,214,255,231,135,71,229,245,255,232,201,243,253,250,127,23,79,139,5,123,163,118,112,251,43,186,242,60,2,141,227,115,54,17,82,202,238,72,136,23,202,145,247,129,126,182,74,65,23,170,19,187,254,49,114,84,81,7,217,203,187,233,18,213,53,60,140,150,75,50,65,66,140,242,36,66,15,188,147,243,233,209,191,132,60,253,94,0,47,143,191,165,187,206,217,6,63,164,9,137,56,102,90,24,19,26,107,39,28,37,210,160,169,179,58,247,157,186,102,66,60,206,166,210,21,169,117,29,134,3,186,192,236,202,41,252,166,214,86,211,158,83,27,10,73,143,40,133,241,53,138,15,66,200,114,155,146,95,87,43,39,159,172,92,215,17,47,84,209,196,240,175,50,166,171,167,200,212,79,146,156,76,95,170,191,45,218,193,185,14,171,236,230,90,109,90,187,233,239,164,249,169,253,7,124,33,43,186,210,60,245,126,130,248,12,51,140,124,134,209,60,139,56,73,34,140,20,153,165,125,68,56,34,41,138,113,128,211,212,103,87,136,83,195,101,11,93,48,194,165,77,79,27,17,192,90,228,167,202,126,196,82,142,18,159,249,115,204,49,123,129,160,71,42,250,187,32,41,238,171,158,231,254,21,26,99,68,210,52,195,169,100,55,195,192,47,177,217,194,100,97,177,201,214,70,139,142,201,94,185,41,194,170,82,204,186,247,9,79,73,202,49,107,50,69,88,108,186,90,185,169,134,210,117,76,23,9,61,221,230,212,106,130,17,15,204,216,114,169,203,173,86,158,106,27,51,251,183,134,185,168,92,33,192,28,55,57,9,110,168,44,153,216,233,245,209,195,154,97,126,205,98,78,120,132,87,171,247,243,36,90,174,192,10,154,51,190,113,92,38,233,116,221,153,184,171,205,145,171,107,170,50,181,235,191,208,153,119,104,3,216,176,254,31,14,159,61,45,175,255,207,158,61,219,175,255,119,241,8,114,29,60,42,22,121,107,133,207,29,74,213,46,46,229,98,215,44,254,85,71,40,176,108,181,82,18,68,31,230,74,144,55,93,222,172,233,77,214,64,117,55,40,186,27,76,25,22,194,208,49,250,189,59,107,66,195,90,150,91,10,236,165,172,193,156,80,72,144,86,6,133,253,174,105,255,220,238,211,40,255,37,89,237,100,15,184,94,254,63,125,114,116,244,68,199,127,29,14,69,185,163,225,240,233,94,254,223,201,51,24,160,215,52,196,104,138,99,204,124,142,67,52,190,66,37,57,114,16,204,195,136,196,66,126,33,16,40,175,229,111,45,143,86,43,15,189,249,136,62,124,60,69,111,223,188,63,245,186,131,1,74,105,198,2,60,18,34,8,92,97,39,68,232,59,93,189,22,20,47,139,149,64,252,58,244,38,227,180,16,239,98,213,48,118,28,122,107,106,175,75,32,251,100,157,86,241,43,119,179,139,236,238,104,101,205,23,206,106,189,51,85,239,172,169,158,214,145,139,90,178,130,93,202,80,160,173,130,117,45,234,213,185,180,126,59,118,169,201,56,181,167,214,201,231,214,169,25,217,110,85,130,6,132,57,118,73,160,148,245,74,203,154,40,166,175,83,154,168,61,191,40,215,188,245,92,183,243,212,37,146,53,161,84,5,46,243,143,240,235,150,109,47,53,177,87,102,120,192,192,62,160,232,201,0,1,19,39,37,211,141,52,162,72,63,53,240,147,241,85,20,16,124,197,151,36,229,159,222,126,62,157,100,209,15,167,167,39,159,50,57,94,171,148,218,197,214,30,184,27,252,169,138,177,36,168,28,152,151,54,115,82,183,114,35,28,35,79,117,254,242,228,253,251,120,66,61,112,202,143,97,176,61,52,52,43,230,98,160,22,230,99,196,89,134,75,253,40,121,80,234,154,50,0,178,234,226,47,94,150,220,250,106,1,176,80,42,59,46,119,99,244,108,252,172,147,81,155,249,69,19,142,205,22,162,141,194,64,230,4,50,152,193,233,118,156,201,156,59,221,54,22,41,48,45,181,41,54,152,113,158,88,214,165,250,73,80,35,110,209,32,195,41,159,100,145,99,6,156,129,149,194,60,207,194,6,79,74,89,215,43,191,5,192,122,109,59,14,104,136,131,129,94,23,101,136,136,238,213,0,162,205,0,164,108,113,218,22,215,145,141,109,139,11,64,11,147,156,64,184,69,116,237,17,45,77,82,78,153,18,115,101,64,71,60,94,103,5,56,82,4,170,200,66,242,191,25,67,89,99,141,148,235,177,253,177,26,249,168,190,173,13,125,212,245,55,198,62,170,130,58,250,81,33,46,15,127,212,159,77,142,173,255,181,117,104,105,175,219,29,60,66,143,90,60,72,9,84,244,6,79,192,51,138,198,237,234,61,26,20,162,68,187,10,228,115,249,189,148,35,37,157,163,108,100,108,42,190,73,238,151,221,19,170,102,199,118,70,205,175,182,73,211,214,21,235,215,173,245,75,205,53,229,124,77,191,133,112,223,32,197,91,34,85,58,86,182,177,189,162,80,16,2,78,181,133,186,11,94,165,109,43,147,152,99,54,129,227,98,105,34,22,48,106,103,181,28,180,207,254,213,15,56,138,104,126,4,34,69,130,25,28,155,151,133,130,234,75,165,188,17,33,91,174,144,68,87,197,9,203,250,105,235,148,93,234,214,152,188,213,120,116,180,230,38,48,75,97,192,46,120,110,146,201,149,21,34,105,13,188,26,35,105,196,117,170,128,76,84,134,70,197,87,174,195,65,37,206,184,17,22,3,169,91,0,163,116,207,31,177,31,146,120,250,154,206,231,56,6,97,156,251,244,170,64,148,229,210,19,164,83,214,84,196,82,83,199,52,198,80,53,217,184,138,180,207,244,11,201,83,61,132,25,163,12,153,107,131,225,228,88,75,194,103,102,17,187,153,124,72,167,204,39,145,49,38,53,164,218,81,152,178,222,28,85,13,215,87,70,245,200,164,161,62,170,31,164,108,162,213,128,31,149,28,164,251,245,92,124,91,40,168,140,47,224,151,72,105,139,158,10,129,237,35,134,191,32,107,224,61,228,62,50,221,138,149,191,111,95,130,212,107,24,107,115,219,37,36,108,106,254,122,67,94,243,51,223,20,129,208,182,87,54,203,167,183,133,164,108,39,167,110,87,238,220,178,36,49,142,251,64,227,46,139,3,177,44,42,101,188,204,83,242,83,129,77,56,225,85,92,164,212,135,156,153,206,126,240,227,48,194,204,77,23,172,88,180,150,171,62,170,165,36,29,78,37,6,193,49,123,151,197,65,15,185,158,167,200,17,122,106,185,68,90,236,182,19,48,172,122,154,140,115,246,19,76,48,58,70,15,77,30,91,174,10,54,210,223,75,124,178,20,90,39,244,146,230,161,20,19,151,225,47,210,139,172,28,57,33,222,117,24,230,25,139,197,27,168,2,47,87,221,110,103,6,131,20,208,66,43,89,28,52,242,235,152,134,87,38,34,154,135,87,140,15,58,77,23,204,115,141,201,206,2,220,243,76,209,147,55,239,217,130,182,215,211,217,80,204,150,90,78,102,175,38,176,164,232,166,44,122,224,208,214,216,126,224,47,134,33,200,153,130,77,77,205,202,96,128,166,152,195,228,76,24,157,11,114,128,247,162,208,27,159,251,2,145,1,191,244,254,229,71,25,118,167,176,112,74,52,254,15,190,250,1,251,33,102,61,207,125,4,31,212,207,124,182,143,243,86,132,0,168,129,179,180,251,128,159,11,209,81,65,9,146,50,20,29,230,227,238,163,98,170,107,195,107,202,20,146,71,119,210,115,209,44,116,226,213,10,104,217,220,95,233,185,104,71,142,164,104,106,50,231,222,91,65,25,19,215,201,226,243,152,94,32,150,38,178,57,136,138,26,161,191,157,58,125,249,98,187,89,72,197,44,164,9,226,20,193,40,133,96,210,239,240,60,225,87,214,180,120,159,210,4,29,139,143,18,219,240,235,97,205,112,150,229,45,94,87,227,6,208,17,147,168,107,28,39,182,147,105,166,60,44,4,11,91,216,130,69,69,192,41,65,34,75,231,235,253,206,196,217,86,189,154,218,210,26,161,111,232,20,176,49,139,241,133,107,107,14,185,80,203,191,215,146,118,37,56,249,19,14,22,63,165,83,119,94,242,186,208,68,38,222,173,186,101,137,195,22,150,196,33,166,196,49,231,194,157,247,209,67,101,89,107,86,230,150,18,150,85,207,20,205,69,71,215,19,72,243,77,206,40,85,221,47,135,163,81,161,171,76,15,73,229,110,213,218,157,109,141,165,123,66,209,14,240,35,57,88,29,31,224,248,179,120,81,216,253,171,91,125,85,230,101,28,66,24,59,208,42,229,213,242,7,70,5,65,162,208,104,25,249,134,250,8,106,215,230,109,131,185,73,151,152,108,222,226,215,108,14,172,61,190,185,207,209,67,55,117,127,28,135,245,226,188,152,194,53,101,64,62,52,105,217,70,151,57,38,75,93,235,247,109,64,216,80,182,13,40,48,71,6,8,50,182,26,149,55,118,229,141,76,94,172,178,95,147,37,235,122,181,4,105,215,166,128,233,102,10,144,217,224,54,77,255,58,54,200,155,168,5,71,249,177,152,36,97,46,96,238,37,122,180,25,202,158,36,141,57,90,51,123,121,115,91,130,191,161,109,115,97,82,34,230,82,141,14,50,89,200,197,162,91,14,126,104,32,73,99,232,219,140,60,167,200,91,196,192,198,62,110,134,9,205,17,215,153,252,245,220,179,188,233,232,55,113,157,177,133,218,149,182,145,35,110,147,190,161,245,99,100,45,114,243,66,47,172,177,8,23,222,164,53,71,167,141,193,195,181,81,195,109,246,224,104,205,38,28,245,138,64,130,223,179,29,162,228,68,29,200,19,98,64,91,243,225,177,233,88,162,171,232,1,190,162,225,149,52,198,179,226,69,75,181,197,164,97,213,251,137,207,103,203,165,78,81,39,36,184,238,239,39,8,9,95,173,70,230,75,81,252,116,158,68,90,226,223,6,12,114,85,88,106,255,122,247,22,250,232,161,31,105,224,115,236,206,85,218,10,117,164,43,207,86,85,202,132,158,185,253,16,172,12,110,63,170,70,221,150,183,179,204,227,71,235,102,13,57,143,28,177,178,107,17,168,162,17,84,170,16,245,246,225,165,183,92,22,156,212,48,251,58,142,65,154,4,111,17,77,162,53,183,39,166,68,48,230,50,7,211,49,104,194,2,205,233,214,123,193,26,165,37,39,153,116,92,188,185,71,66,190,5,32,170,148,188,251,78,118,73,202,82,12,54,147,114,1,253,13,105,217,34,129,122,98,190,13,76,153,29,111,166,106,19,72,71,42,164,58,187,69,253,191,141,39,164,114,129,59,83,123,87,177,112,160,48,95,61,32,35,138,82,126,117,140,139,42,169,117,158,133,207,76,131,77,169,169,227,92,117,54,94,42,221,70,212,108,11,82,125,59,106,115,147,135,172,140,144,229,218,177,243,152,26,43,238,103,203,144,154,154,186,98,98,156,126,174,134,41,227,210,41,216,243,92,247,81,201,170,224,198,36,234,245,250,133,90,86,46,223,214,62,160,26,178,118,119,246,233,188,222,54,194,47,217,205,72,219,146,62,224,11,249,254,13,73,19,159,7,51,204,92,163,49,99,15,39,101,91,58,66,63,255,162,38,79,190,89,90,200,170,42,114,85,199,178,27,106,106,214,220,108,82,14,45,167,180,110,167,147,27,226,21,129,13,44,239,86,165,232,123,106,174,6,90,225,119,140,121,50,31,213,200,114,233,189,203,162,232,234,255,100,126,68,38,4,135,175,231,138,22,138,254,222,101,113,48,106,60,223,145,134,104,214,208,141,172,123,19,19,103,191,210,38,132,138,174,83,12,107,224,184,93,21,185,177,183,219,81,153,107,187,155,148,167,17,8,171,50,185,150,140,208,207,43,18,135,36,158,2,135,60,210,75,163,122,185,172,148,46,49,204,53,180,246,218,22,107,223,162,156,84,193,165,171,58,74,32,214,166,154,239,227,36,227,35,36,13,2,189,218,69,223,216,11,214,236,43,209,170,185,113,121,36,51,146,141,167,139,160,197,177,226,54,231,110,77,221,34,195,24,187,8,110,237,0,173,169,235,53,8,249,225,244,244,68,10,214,145,165,36,104,213,114,205,68,157,248,156,99,22,143,242,41,122,27,79,40,147,81,169,53,218,168,211,107,110,74,168,34,35,237,195,90,183,193,104,34,192,50,138,119,190,81,88,110,234,183,118,29,111,126,98,18,181,105,80,44,238,205,232,50,53,184,26,180,25,202,108,59,160,244,115,27,186,233,70,4,90,227,150,106,118,123,136,55,163,211,106,190,25,173,13,175,205,13,95,139,42,182,243,75,77,193,6,247,119,169,101,155,111,170,138,205,229,118,202,72,25,226,170,112,218,164,77,148,203,239,90,45,176,208,98,98,101,213,90,187,52,213,67,165,87,226,52,216,94,69,164,172,170,29,174,139,57,184,134,46,88,198,166,108,119,219,57,80,136,220,181,118,102,14,53,5,137,82,51,250,53,179,183,129,168,87,21,13,95,110,41,183,76,124,128,152,42,159,123,223,154,150,115,221,152,173,243,186,105,105,239,215,71,233,130,149,20,99,219,96,190,117,58,134,218,30,218,46,241,138,52,204,28,7,26,128,218,211,215,186,13,46,244,88,206,137,160,167,34,241,99,18,180,200,135,94,96,23,212,153,81,158,219,181,167,93,149,80,75,175,144,242,52,33,78,193,7,164,52,80,112,191,201,199,218,114,168,158,177,97,239,235,160,1,29,18,150,179,204,207,191,88,141,171,189,164,80,107,183,148,13,183,191,253,184,163,109,199,189,239,133,203,34,71,43,157,13,155,123,243,201,133,164,145,39,185,126,185,190,141,157,107,205,50,175,40,66,104,190,147,8,7,220,19,191,62,78,202,59,145,229,170,70,229,85,243,220,84,87,27,42,43,117,91,201,219,124,5,221,66,24,8,78,41,88,182,94,52,52,72,4,100,45,221,118,138,187,182,17,54,146,16,175,25,96,179,57,22,102,219,236,61,235,140,157,198,85,73,229,56,16,157,84,25,242,105,215,121,156,152,117,183,240,48,105,168,166,49,223,28,185,97,6,104,183,210,19,111,93,218,221,118,148,133,10,24,188,121,160,197,141,188,171,183,240,235,175,117,180,167,9,79,145,231,121,42,139,190,10,39,70,46,75,147,60,18,32,79,224,126,77,167,255,237,59,46,9,39,171,247,198,152,0,180,101,40,72,155,224,22,179,72,253,8,155,198,81,246,252,50,91,146,127,95,23,167,77,61,110,118,25,51,250,189,57,38,203,168,178,220,7,119,68,12,235,220,231,110,134,196,237,97,185,43,244,54,132,140,155,145,43,173,228,247,251,121,18,233,115,83,104,78,45,25,106,92,178,164,181,241,173,139,45,78,13,92,23,215,253,88,85,13,136,1,119,63,255,98,161,78,0,188,240,25,106,113,33,32,82,241,8,162,153,234,12,108,172,189,220,56,26,125,156,218,10,119,75,217,255,72,99,236,13,158,248,89,196,245,44,155,152,201,207,155,84,25,155,66,197,112,70,240,223,122,121,180,75,168,106,251,50,244,165,181,43,248,159,34,162,233,198,75,174,60,87,15,106,189,220,42,243,213,187,21,89,84,187,64,202,35,129,214,187,230,84,69,180,200,88,138,110,103,214,38,138,165,219,17,172,60,131,31,200,12,104,129,128,144,25,58,46,162,75,84,161,99,244,208,40,182,92,117,59,112,15,231,113,142,134,127,19,62,147,93,194,121,67,109,191,125,213,101,175,219,89,73,214,17,61,8,80,232,57,26,83,26,229,253,65,240,202,49,154,149,195,109,58,70,192,74,37,242,133,202,11,83,106,246,41,106,16,36,214,224,162,192,143,99,202,209,24,35,206,252,56,157,96,198,228,197,50,70,119,78,175,184,46,77,182,32,88,1,29,11,124,23,111,100,56,74,101,31,86,218,229,192,181,165,125,52,79,225,50,95,200,8,1,40,123,29,209,24,235,43,105,224,158,63,81,47,196,19,204,84,169,147,140,191,242,131,115,93,102,158,78,123,221,110,103,158,78,85,125,65,82,159,78,94,11,202,116,155,44,130,61,163,130,31,69,24,27,230,144,235,152,80,42,237,189,76,18,176,15,229,14,13,245,93,98,166,174,118,45,60,29,26,97,203,75,234,13,87,93,89,185,255,119,157,242,101,72,186,212,103,204,224,94,29,200,14,44,166,198,149,72,173,188,127,23,249,252,21,240,173,192,110,224,71,17,48,237,232,24,205,253,115,236,150,22,195,62,26,246,81,132,99,55,240,68,177,222,183,226,111,248,171,103,84,62,70,126,146,224,56,116,245,155,62,146,229,61,207,219,80,46,47,213,74,12,172,237,177,238,122,93,168,221,43,199,164,117,132,210,62,170,37,102,51,155,106,160,229,216,251,120,65,207,177,17,168,6,97,86,186,107,1,126,57,223,42,42,197,152,169,112,181,214,194,110,170,130,196,242,240,189,206,35,25,14,246,168,224,198,58,239,173,50,47,214,133,133,89,81,97,13,251,138,157,175,25,187,211,82,173,192,182,223,192,218,118,221,17,24,225,145,109,37,230,94,26,222,178,52,52,24,1,124,224,132,140,176,54,17,198,33,218,170,90,222,43,14,173,208,113,227,169,85,77,61,179,241,84,165,111,233,218,18,239,222,5,116,229,154,201,192,51,183,20,133,235,154,148,147,229,49,246,155,79,241,44,73,106,30,130,108,136,253,189,212,50,188,93,236,134,132,83,71,224,229,142,174,27,116,235,218,228,27,102,84,134,89,45,15,106,97,248,75,53,7,119,221,24,26,91,90,119,193,117,93,67,166,76,201,157,115,13,161,111,197,22,214,72,124,85,36,143,20,172,13,63,132,34,230,237,185,141,209,135,237,227,2,213,94,189,146,251,167,28,20,184,49,210,207,68,65,167,46,176,174,28,180,83,222,141,52,182,96,141,88,124,179,47,16,110,219,98,141,36,89,103,29,89,71,197,69,0,93,67,171,213,16,186,237,131,157,100,147,45,131,221,114,154,171,103,136,82,148,151,29,228,117,35,232,54,205,129,128,173,28,99,101,184,187,55,50,96,83,152,85,83,34,130,53,97,86,77,116,116,253,65,183,37,64,1,238,206,68,204,125,99,209,140,85,179,47,140,186,239,156,200,127,166,167,54,255,183,82,216,206,118,148,2,124,125,254,239,195,39,71,143,135,246,253,15,71,195,103,71,79,247,249,191,239,226,105,123,97,227,135,117,151,59,108,149,106,88,233,211,213,139,22,154,238,93,50,210,202,46,139,204,183,132,90,9,25,59,133,131,75,229,134,74,253,215,123,241,190,151,103,250,235,108,233,14,167,194,13,138,254,139,196,140,157,138,174,81,214,59,242,74,80,218,33,212,41,41,121,219,166,245,180,46,80,250,160,239,69,90,127,241,84,126,67,147,145,7,209,76,149,170,238,175,122,175,174,108,246,83,184,146,220,184,179,40,77,112,64,38,87,144,232,3,170,129,99,18,68,62,229,105,202,212,196,213,164,133,245,60,207,27,72,85,39,25,191,184,188,188,212,247,94,117,154,82,176,2,202,215,103,96,149,69,54,39,96,133,98,249,233,97,167,99,102,95,237,24,185,119,141,63,225,102,169,193,35,228,88,4,228,32,134,231,0,38,92,224,133,24,158,250,44,140,112,154,10,100,205,232,133,186,191,41,194,41,92,12,21,146,5,9,113,232,229,25,77,77,255,141,13,180,90,123,3,107,179,59,199,87,164,212,140,27,37,62,29,60,66,223,171,219,0,96,40,58,43,44,104,182,97,225,185,114,49,195,49,82,174,76,0,46,34,41,2,60,240,153,31,11,182,194,95,50,63,66,156,138,93,237,182,104,2,182,137,4,129,154,61,12,107,182,34,242,26,165,92,135,46,231,70,29,60,66,111,50,8,16,4,162,206,24,19,26,119,68,105,2,151,104,33,124,137,131,12,6,100,93,214,69,38,37,0,197,198,72,1,137,198,87,72,222,180,221,23,195,84,69,229,84,202,68,83,137,88,75,67,137,34,168,164,251,151,237,229,245,225,98,248,84,160,104,172,33,49,73,165,20,191,210,112,19,120,145,103,129,50,121,155,231,3,239,68,251,1,246,144,139,191,148,176,40,27,236,161,109,110,16,111,56,123,211,229,205,195,182,131,250,131,180,162,168,113,114,86,36,219,101,178,209,147,243,105,67,187,39,231,211,55,132,225,128,147,69,105,233,169,41,188,121,49,50,250,107,188,246,231,1,147,224,87,128,42,70,208,6,170,162,116,11,176,138,30,215,221,70,4,147,106,12,193,56,111,52,238,100,51,230,234,24,185,242,108,9,57,147,177,247,183,212,177,196,169,231,152,133,101,62,127,121,108,89,200,135,94,33,142,242,16,144,186,110,140,83,82,243,75,245,140,116,253,216,10,60,52,143,77,17,87,187,177,201,194,215,25,91,209,77,121,108,234,75,171,177,93,215,89,203,140,208,85,36,85,201,38,173,222,215,104,45,114,87,154,154,187,82,41,48,75,246,115,149,149,77,47,156,205,196,209,19,235,169,183,117,250,88,184,191,240,21,9,37,175,208,216,143,138,155,10,81,26,224,216,103,132,162,132,81,33,128,197,187,136,78,73,128,92,161,91,48,60,193,12,199,1,70,52,142,174,250,40,137,176,16,73,115,26,146,201,21,242,83,144,162,56,236,121,221,206,68,246,213,129,131,157,106,102,55,183,167,110,207,123,131,199,217,116,226,58,2,34,229,149,139,24,14,176,224,98,240,252,132,244,150,29,189,21,62,62,70,132,122,111,63,190,43,159,224,202,147,214,154,244,134,157,34,95,156,42,51,6,133,213,176,186,124,192,23,202,240,226,14,69,95,2,246,179,190,204,217,36,48,48,58,86,11,192,207,158,231,253,34,163,220,151,142,142,153,117,126,32,8,33,248,131,70,62,114,86,178,219,166,193,145,20,249,99,154,113,177,214,164,130,178,96,148,186,47,209,189,152,160,183,82,139,19,75,244,203,16,22,45,31,189,35,56,10,61,85,224,147,186,1,90,172,101,206,103,0,201,65,36,70,175,25,246,57,150,47,36,161,203,213,14,71,161,84,28,174,104,134,46,252,24,250,191,160,236,28,10,149,91,117,212,1,9,52,249,50,12,117,4,100,169,65,184,40,115,109,131,36,4,115,242,216,51,225,178,79,216,255,182,176,81,208,87,121,4,92,134,191,120,250,160,166,215,131,195,244,78,201,70,242,153,251,140,187,99,141,181,210,215,2,112,119,220,23,160,64,185,177,247,142,196,36,157,149,237,45,111,227,208,29,203,94,42,201,8,193,156,51,174,26,91,74,212,5,228,181,146,215,64,230,34,76,236,58,26,196,197,111,77,44,88,14,94,187,149,7,131,1,242,35,216,61,252,172,57,104,181,189,148,248,108,249,161,109,43,45,54,50,254,31,159,243,36,234,83,239,255,165,36,118,253,40,234,131,224,186,75,222,210,1,201,5,99,229,249,206,198,189,45,164,184,129,179,191,43,72,254,190,17,75,52,145,219,41,26,123,178,9,65,147,249,241,28,224,163,94,248,52,243,244,13,150,250,186,92,232,121,90,214,219,229,244,34,97,224,206,57,253,26,252,42,122,32,130,90,135,47,16,65,223,161,167,47,16,249,246,91,152,248,141,60,187,137,101,111,133,99,119,205,176,237,86,74,153,117,94,175,151,181,132,218,71,4,216,172,153,151,91,178,242,102,78,110,191,72,150,121,183,56,145,168,230,84,110,203,59,187,187,92,0,248,225,159,177,207,174,224,196,124,100,82,219,142,185,129,204,245,197,228,245,124,112,115,153,54,24,32,56,61,182,168,2,13,6,232,123,204,145,38,77,217,16,157,232,204,5,170,158,207,208,92,81,21,188,32,19,180,48,92,57,7,3,212,153,163,99,228,252,19,178,121,199,14,188,42,28,49,245,119,69,151,11,57,158,85,119,19,135,222,6,131,238,152,63,27,217,211,185,192,81,64,231,24,57,232,91,52,7,68,203,239,200,215,217,176,72,108,137,175,174,148,104,13,249,199,155,249,182,29,219,110,228,90,197,119,99,43,157,121,77,222,202,131,253,25,224,221,62,155,206,255,224,110,209,27,30,2,174,63,255,123,252,236,217,179,199,165,243,191,195,231,195,163,253,249,223,93,60,45,206,255,234,142,16,54,157,177,53,155,143,119,112,154,216,226,44,81,94,157,26,171,110,220,177,159,98,241,67,52,77,51,240,164,135,14,78,124,62,51,15,89,140,49,152,209,181,242,197,193,245,142,111,238,252,92,115,219,99,205,198,67,205,173,206,52,43,71,154,8,33,228,8,233,33,86,213,110,183,195,89,18,220,206,109,160,246,113,105,228,199,211,193,156,6,231,131,41,21,255,56,221,142,89,64,40,141,60,152,49,184,66,146,76,174,64,234,49,184,172,116,39,71,176,118,176,114,233,34,202,230,147,78,248,184,241,176,51,47,213,234,194,201,182,71,158,165,72,45,56,246,220,242,192,81,177,70,64,231,115,255,51,78,124,121,149,248,72,27,230,145,171,219,251,10,197,123,200,49,188,185,157,158,157,169,186,37,161,111,73,231,237,194,203,100,177,210,56,242,97,148,63,56,125,167,70,62,58,103,78,209,147,26,168,83,156,182,237,178,113,57,206,162,241,154,219,33,7,131,41,29,233,235,221,209,148,138,237,2,226,36,188,146,151,79,31,10,92,112,70,230,140,76,103,146,214,236,11,126,161,212,17,236,183,44,138,52,74,125,69,145,159,114,244,21,193,21,208,103,169,220,111,64,86,96,179,111,193,141,83,28,163,131,16,164,2,184,109,31,167,60,27,15,150,203,7,201,225,106,37,254,5,161,189,90,157,137,194,222,148,162,3,37,62,143,69,153,163,213,10,29,164,56,154,156,153,111,5,7,28,28,200,27,231,155,218,243,228,141,178,212,136,66,172,158,170,182,32,188,235,28,153,90,199,96,155,14,77,173,115,165,253,177,233,125,28,155,218,243,181,241,112,209,42,190,229,241,98,165,43,227,128,209,254,182,227,227,83,155,204,90,142,81,21,191,214,24,141,174,42,99,212,223,90,142,17,110,71,84,120,129,83,81,53,88,112,211,16,91,235,44,14,49,75,3,202,112,136,22,152,165,130,110,16,157,88,8,149,21,243,206,251,40,75,113,8,158,76,177,92,50,46,47,223,49,58,87,123,100,136,12,151,244,135,30,13,12,15,7,35,10,89,99,240,111,233,25,252,175,78,122,231,114,195,181,136,70,10,206,30,50,116,81,102,68,32,95,163,101,61,85,118,203,106,55,175,109,84,230,0,25,230,140,224,5,78,165,155,12,101,50,61,34,24,77,164,107,77,198,192,144,34,62,235,203,109,33,160,77,188,168,51,117,129,169,196,203,111,16,171,235,213,29,55,93,103,82,178,166,233,243,99,105,43,19,48,105,147,3,14,95,93,113,156,246,193,136,18,248,49,162,99,161,90,1,84,227,43,142,181,93,219,30,17,167,232,39,159,165,51,63,242,186,29,134,191,136,146,169,52,180,88,205,186,96,187,104,188,21,113,48,64,175,21,60,239,99,194,145,31,69,244,34,5,80,56,21,90,158,114,74,242,109,140,249,38,100,125,116,49,35,193,12,145,20,225,47,25,89,248,17,150,150,160,127,198,115,19,68,79,244,224,106,88,251,150,117,231,123,204,255,249,113,50,73,49,63,205,75,24,102,23,134,191,116,243,76,63,76,27,103,110,48,251,73,116,181,221,220,215,244,185,113,238,117,157,219,157,251,52,89,59,247,141,161,165,91,205,125,142,175,107,204,124,154,168,153,87,144,174,153,121,85,194,156,249,52,233,22,43,131,144,121,173,116,101,152,183,83,156,242,179,205,199,60,46,71,143,212,54,207,59,5,187,182,157,172,94,30,4,137,13,179,21,222,37,173,235,10,145,96,111,68,23,140,128,223,131,80,253,164,217,219,235,118,2,206,96,63,36,55,115,222,7,124,241,154,198,156,209,40,194,204,229,189,110,71,5,157,115,22,105,35,100,15,28,92,215,196,96,152,105,59,196,102,123,44,154,253,137,6,231,155,226,78,93,209,77,79,155,75,97,63,83,106,180,69,123,53,241,82,235,218,85,71,102,91,182,171,2,53,85,187,36,166,44,212,105,185,140,224,195,71,10,171,175,225,8,114,88,148,44,58,109,44,9,230,245,4,7,98,171,50,198,51,127,65,40,243,84,88,73,91,236,123,111,255,247,228,237,235,83,183,148,250,89,245,245,50,190,114,123,125,100,254,234,137,127,78,201,92,114,231,220,123,67,33,108,70,208,186,219,124,153,172,14,246,109,119,153,236,165,26,65,195,12,23,48,195,193,83,51,116,157,203,42,120,98,45,177,160,200,15,71,59,157,177,190,250,148,193,77,172,245,23,159,218,153,36,58,50,195,157,67,98,237,139,12,171,140,211,211,78,33,157,180,105,48,114,134,139,193,72,191,7,79,1,219,184,94,247,192,130,47,1,177,72,37,63,205,182,94,247,81,218,171,58,76,137,87,231,109,177,108,196,53,137,106,85,156,90,72,220,126,168,16,177,36,221,53,0,84,117,184,88,35,192,188,242,29,242,13,61,153,190,60,27,156,118,214,72,146,182,240,86,81,171,222,52,55,45,79,97,160,176,34,223,247,241,71,49,105,246,228,201,112,226,214,20,180,129,29,210,26,110,72,147,38,110,40,152,1,82,35,52,48,131,201,11,21,86,144,219,71,71,59,119,4,109,9,174,202,9,181,218,75,193,9,182,116,45,51,130,70,121,208,235,218,147,213,140,126,5,17,160,191,178,58,102,66,217,16,11,238,53,79,134,75,113,223,173,69,181,189,230,179,36,240,94,249,193,249,148,209,44,14,149,164,117,165,230,241,37,35,12,123,31,72,228,202,52,9,230,75,202,213,123,9,198,222,9,163,173,19,198,27,121,96,111,185,89,104,9,93,235,102,161,63,182,114,179,208,133,11,55,139,193,0,125,204,120,146,113,132,125,161,163,198,226,207,196,103,254,28,115,204,144,27,204,112,112,142,184,247,35,157,78,16,133,146,125,196,178,24,253,58,165,146,60,15,22,191,246,212,248,78,103,184,228,5,32,180,245,177,34,80,130,195,130,68,85,13,217,112,67,242,102,75,211,17,139,222,8,253,237,139,211,111,222,101,246,12,87,149,110,167,179,117,227,139,181,141,139,38,107,93,82,164,135,97,149,27,86,93,40,127,92,164,180,51,150,184,218,26,185,195,98,154,52,58,44,54,56,31,50,236,159,23,190,107,230,156,42,97,36,35,86,126,75,19,154,38,98,66,97,160,10,249,98,21,200,167,80,35,101,171,121,132,54,23,165,54,243,150,26,166,169,148,96,103,109,126,157,253,118,233,143,182,93,218,111,130,246,155,160,223,210,38,40,207,16,209,180,15,106,156,205,117,118,172,93,236,153,182,218,35,228,126,215,22,213,64,51,213,65,77,26,41,165,32,149,201,26,66,177,41,101,237,38,65,17,75,71,166,102,107,214,251,205,173,156,156,75,57,153,119,176,115,44,178,107,40,96,203,25,225,110,101,7,184,223,130,236,183,32,98,11,242,106,191,5,185,191,45,200,250,198,175,179,5,169,217,75,148,151,153,173,241,118,59,138,254,206,244,252,58,84,212,233,248,251,35,145,63,139,142,223,226,72,228,94,116,252,93,104,252,37,61,123,219,45,64,59,85,124,173,9,182,80,196,133,182,178,43,75,242,150,166,228,150,182,228,13,123,10,83,81,4,213,235,246,236,201,219,24,148,107,54,21,219,168,161,77,219,155,245,42,106,115,156,164,161,160,174,186,59,56,221,184,185,34,123,171,182,244,77,218,225,31,35,4,169,46,0,233,181,147,203,230,26,29,112,163,10,88,19,51,84,209,255,110,91,249,216,86,103,219,189,213,248,86,247,65,125,52,190,230,86,104,39,134,230,63,163,133,120,48,64,47,83,228,199,58,25,90,31,5,192,52,38,17,168,87,105,83,164,30,18,173,248,113,136,178,20,188,177,124,174,203,249,210,57,203,70,170,242,118,250,164,35,42,7,3,157,237,42,196,11,28,209,100,14,66,146,25,98,198,110,32,23,6,33,78,9,195,161,122,45,26,146,89,169,114,79,38,28,246,1,48,221,86,89,56,217,94,86,133,168,82,110,96,85,84,184,169,26,90,189,191,223,159,86,184,166,183,46,90,141,101,181,94,56,117,87,229,73,211,58,75,205,164,153,142,122,251,73,187,86,20,237,22,49,180,107,12,147,27,118,169,197,98,34,246,153,235,119,172,8,33,137,85,159,77,211,34,63,181,190,89,179,102,191,145,127,171,139,134,47,62,214,92,176,103,220,175,41,96,72,243,108,45,118,159,48,43,242,82,48,18,79,243,215,0,160,250,55,127,41,38,238,45,99,242,118,30,104,190,104,71,44,78,31,223,124,28,9,2,144,202,95,224,167,56,85,171,208,15,152,225,191,155,66,92,202,96,237,97,170,181,192,32,160,76,123,147,94,209,140,201,68,126,162,13,88,12,99,121,137,235,216,79,73,0,125,56,125,241,90,192,56,2,72,229,46,35,224,151,35,212,184,128,43,203,239,151,81,157,236,116,94,58,186,132,88,184,106,24,53,15,18,215,37,87,240,95,133,154,145,140,49,236,163,46,124,40,166,64,101,161,226,188,200,63,37,103,165,192,32,247,62,101,177,203,185,23,203,244,159,98,3,86,71,64,230,125,173,219,7,148,153,45,164,165,203,1,114,83,137,89,104,93,132,187,89,110,225,179,226,222,62,235,11,153,160,177,84,123,142,81,90,82,179,184,39,230,205,131,235,16,244,15,121,49,128,91,108,134,122,226,95,206,61,77,127,54,30,58,220,123,43,250,172,87,72,108,246,180,123,215,251,217,99,208,80,116,235,250,138,218,190,209,101,207,190,71,215,56,252,89,35,56,74,56,248,171,190,173,247,13,198,201,219,47,153,31,185,160,10,229,195,78,19,117,174,180,181,166,103,98,67,42,125,215,198,136,24,214,148,138,253,177,208,4,65,84,131,58,95,210,4,13,160,77,117,222,2,100,55,80,44,52,20,185,238,104,34,172,52,47,249,95,250,122,225,166,244,232,7,229,76,233,59,141,255,174,141,255,23,18,233,108,74,189,43,127,126,179,204,223,242,89,31,255,63,124,62,60,122,106,199,255,31,62,127,122,116,184,143,255,191,139,7,68,115,178,33,34,255,65,138,23,76,221,26,84,27,39,57,84,17,255,229,10,250,234,46,217,178,254,145,151,82,23,13,193,215,151,234,111,43,24,31,231,75,134,50,201,231,69,166,17,29,251,209,8,161,111,208,247,240,167,80,71,38,100,154,49,8,43,21,130,70,44,78,105,226,7,120,132,222,20,123,33,81,227,109,188,32,140,198,240,147,67,240,23,38,124,134,25,58,97,52,204,32,206,11,81,102,214,18,237,225,120,113,38,215,117,80,26,74,237,128,118,2,225,99,52,62,72,138,118,112,81,38,245,186,93,57,42,128,91,89,177,43,112,251,73,50,66,203,37,153,160,226,38,38,243,86,166,229,82,236,55,87,43,161,118,40,172,41,209,32,90,125,153,36,17,9,160,177,2,38,8,136,201,82,18,227,52,21,93,104,40,212,101,22,169,141,219,98,201,46,191,183,130,251,140,98,5,117,24,229,52,68,39,50,151,145,206,63,36,128,18,48,140,73,124,150,248,124,54,66,131,44,101,131,136,6,126,4,146,103,48,38,241,0,42,250,66,43,167,162,164,207,174,84,122,100,127,28,229,89,153,227,16,77,152,63,199,160,158,91,120,148,37,68,55,226,117,67,63,226,147,221,145,66,81,83,91,161,207,253,134,182,196,167,250,182,196,151,162,137,9,137,184,154,127,8,174,164,202,193,33,192,9,167,44,133,217,242,163,40,191,105,125,38,47,234,55,226,15,1,239,7,72,6,89,135,120,156,77,35,58,85,47,25,14,232,2,179,43,209,252,123,221,172,188,6,63,149,1,72,57,88,70,134,169,41,101,52,227,112,193,187,84,35,33,193,53,108,135,52,118,53,209,16,193,77,138,118,129,243,19,70,243,148,216,38,149,245,65,9,152,249,11,140,230,89,196,73,18,97,79,81,76,41,252,186,238,54,251,50,17,26,178,199,214,29,53,29,30,32,201,153,192,54,16,218,169,101,75,29,113,131,14,43,180,110,147,173,188,210,157,102,94,113,115,89,169,114,133,11,114,88,19,157,7,98,67,101,88,208,5,30,63,209,140,99,155,79,245,248,84,121,146,140,208,225,209,115,111,232,13,189,67,3,245,40,34,41,199,49,132,159,157,32,63,12,89,142,245,44,197,8,246,187,51,10,177,120,15,150,36,89,121,232,159,41,214,114,142,36,66,190,197,36,232,139,63,185,127,14,51,73,40,35,252,74,119,252,141,248,62,66,152,207,134,234,77,66,25,23,40,246,195,16,253,215,112,56,84,115,40,71,82,5,75,20,111,2,72,124,91,233,158,98,204,5,141,141,16,15,18,209,212,7,249,219,104,74,8,105,249,153,50,148,133,137,174,169,175,92,28,129,237,212,94,115,170,226,48,242,175,48,51,234,64,70,18,202,208,140,243,188,69,78,230,152,102,124,132,14,197,0,209,55,232,39,255,146,204,179,185,201,47,162,12,146,39,5,96,117,75,17,137,209,156,68,17,73,113,64,227,48,245,202,55,55,234,91,147,209,55,72,108,244,196,235,146,136,161,44,191,33,219,143,34,104,97,43,80,132,204,24,203,166,211,246,139,95,93,205,182,18,74,213,201,37,83,1,120,173,120,50,165,199,235,202,216,73,12,89,242,51,223,134,101,47,46,108,113,161,153,204,94,216,37,194,114,110,106,61,243,117,149,27,88,17,76,65,165,58,38,67,34,215,166,103,91,164,244,110,145,95,125,54,197,124,36,196,228,96,144,203,201,209,6,33,165,196,165,197,196,13,18,160,165,8,168,176,124,18,101,83,18,167,64,239,39,240,119,85,211,139,232,84,242,25,157,86,63,194,117,202,126,22,73,177,161,46,90,23,85,236,162,125,148,102,137,204,49,164,23,90,229,11,149,143,232,0,206,59,5,79,7,52,78,105,132,21,15,194,159,41,247,227,208,103,161,170,132,92,213,107,175,216,171,71,130,140,70,8,152,89,131,11,239,0,3,165,6,170,157,10,221,71,86,11,252,72,254,138,232,180,210,60,137,39,180,218,122,84,84,98,84,70,91,71,116,154,22,181,101,47,103,18,39,35,99,147,45,234,72,46,247,64,69,243,4,234,12,5,45,229,148,225,205,237,35,52,247,47,207,82,242,31,44,40,194,36,7,241,78,72,199,134,38,196,162,240,211,171,114,67,130,119,178,36,45,183,21,103,243,49,102,178,181,105,161,45,154,53,253,41,30,161,231,245,149,66,255,10,46,17,57,199,56,169,192,31,208,121,34,168,93,89,252,68,11,255,158,97,208,3,32,80,93,126,53,59,190,239,77,233,254,185,179,7,164,235,56,155,40,227,79,144,36,3,111,236,255,7,71,44,216,89,31,195,225,112,248,236,201,147,38,251,207,240,240,249,209,95,14,159,60,61,28,138,255,63,125,250,151,225,225,179,199,71,195,189,253,231,46,158,113,70,162,16,29,28,4,151,151,52,225,199,206,193,65,202,195,227,224,219,111,15,159,59,93,177,74,192,45,37,104,140,35,122,129,34,18,203,196,57,98,113,253,53,175,42,42,30,76,145,168,202,72,114,28,227,5,102,191,10,217,130,99,216,173,195,194,209,181,139,127,60,186,239,145,239,159,191,52,240,127,16,249,241,244,96,66,217,220,95,75,242,109,159,77,252,255,244,233,179,18,255,63,63,122,250,108,207,255,119,241,252,232,199,211,12,84,139,215,73,210,125,229,167,56,252,24,127,230,87,17,30,161,239,33,239,101,247,53,141,178,121,252,35,153,19,169,20,119,187,223,160,151,25,167,115,159,19,177,231,187,66,33,230,56,224,40,161,176,81,68,126,68,166,114,151,161,188,83,2,26,98,175,251,13,122,63,177,78,213,113,60,161,44,192,40,139,137,32,54,194,175,138,76,62,193,12,182,125,4,10,130,222,226,117,223,96,70,22,248,68,246,242,82,119,50,82,247,171,127,131,94,93,105,149,89,222,236,102,192,145,162,177,24,26,162,18,32,216,206,72,67,100,181,185,31,241,132,139,230,62,198,209,21,74,41,227,104,134,253,16,51,208,232,84,36,66,16,101,33,70,227,136,6,231,221,207,148,241,247,242,77,170,128,81,63,95,137,239,233,8,157,48,12,91,197,223,160,98,85,195,255,159,222,190,124,243,211,91,111,30,238,170,143,13,252,127,56,28,30,150,215,255,195,39,79,246,252,127,23,207,55,232,159,169,63,197,221,238,1,250,255,20,235,201,43,186,162,43,216,26,136,93,13,56,125,101,49,90,16,31,201,212,124,41,250,149,101,241,153,180,127,120,233,236,87,40,3,239,164,21,75,188,243,140,54,169,224,165,144,230,77,22,77,41,61,34,111,68,5,245,204,176,54,251,235,244,161,33,242,57,2,213,244,96,76,98,15,142,157,153,127,129,32,107,106,28,10,57,33,128,84,167,12,208,148,186,139,62,69,17,57,199,82,135,145,18,198,103,24,77,24,198,176,1,202,59,188,242,231,106,31,199,41,29,117,127,253,245,215,177,159,206,186,222,32,239,117,32,91,87,255,156,141,73,12,10,141,216,122,30,171,79,112,168,0,7,168,65,146,156,77,200,24,51,56,71,181,154,145,144,13,224,171,194,152,104,8,254,80,91,217,99,85,166,177,189,95,127,253,213,64,112,16,97,63,6,187,156,24,9,195,50,27,106,138,164,214,69,51,110,161,28,74,203,57,186,111,2,220,63,247,250,212,200,255,127,127,252,244,63,159,79,94,190,126,187,171,62,54,234,127,71,79,42,242,255,233,243,189,252,191,139,39,162,126,232,254,253,191,65,52,157,113,74,163,116,48,144,255,128,228,56,11,241,36,29,48,156,208,209,148,112,111,252,159,232,239,125,244,247,41,225,103,226,93,74,56,101,87,127,239,117,237,23,110,87,219,161,209,49,114,180,236,114,164,147,25,195,115,202,225,195,140,243,36,29,13,6,162,225,11,234,67,170,117,200,238,46,136,144,38,56,86,41,157,243,151,222,148,112,213,202,152,249,113,48,19,173,204,253,148,99,230,244,187,189,46,140,197,249,111,221,225,0,42,142,46,40,59,7,123,184,128,222,233,43,128,242,183,78,175,219,181,223,184,189,110,23,108,122,141,67,2,166,81,144,36,62,7,56,188,129,126,219,187,239,57,221,230,169,225,127,189,30,239,172,143,13,254,63,195,225,227,167,21,251,207,227,189,255,207,157,60,223,252,21,220,45,64,209,233,130,20,80,42,131,231,237,117,131,63,193,83,195,255,90,57,220,89,31,27,249,255,201,227,10,255,31,62,222,243,255,93,60,53,252,47,183,18,7,7,248,50,201,226,233,111,209,104,177,127,118,246,212,242,63,108,60,95,253,243,253,143,111,110,114,237,87,254,108,208,255,143,158,60,205,215,255,231,195,231,67,240,255,221,219,127,238,230,9,130,51,105,103,177,53,220,73,198,51,134,149,105,66,105,186,41,11,82,116,140,126,182,63,122,65,224,252,210,87,254,10,9,20,176,156,92,200,4,225,47,200,13,9,67,222,39,28,249,124,65,112,113,245,150,227,233,219,143,224,113,254,27,232,113,48,24,45,151,104,221,165,93,232,43,138,232,5,102,104,181,58,51,181,113,203,223,166,169,97,247,255,82,18,91,55,92,12,156,6,8,81,175,135,156,51,184,95,231,236,166,32,21,151,45,73,136,236,125,138,98,187,209,220,63,215,168,61,211,23,132,245,55,214,146,111,205,217,170,47,77,231,115,26,143,88,22,115,50,199,103,115,63,246,167,176,121,106,172,17,209,169,108,60,162,211,117,229,50,78,162,1,159,49,236,135,163,200,231,193,204,42,28,208,249,153,188,80,235,108,58,137,252,105,170,254,25,12,70,242,15,85,250,23,177,141,235,54,209,164,97,45,171,144,164,241,109,79,145,191,59,138,28,40,247,29,249,17,254,190,35,50,222,138,50,239,91,88,223,194,211,188,254,55,25,158,183,87,9,54,157,255,28,149,245,255,163,199,79,159,236,245,255,59,121,116,28,78,57,6,199,148,148,17,142,243,111,61,52,204,63,67,189,99,228,248,73,18,226,57,117,242,15,250,182,38,35,136,164,38,134,167,210,69,241,89,247,98,134,161,136,158,228,95,245,157,169,136,160,46,66,114,25,154,211,16,71,210,33,16,136,119,148,59,38,146,56,229,126,28,96,21,205,35,215,14,253,178,8,113,166,113,144,49,134,227,224,234,108,70,98,62,66,255,149,59,114,27,254,204,185,231,177,246,83,14,193,75,121,17,88,30,202,168,228,120,172,220,137,37,10,193,255,55,31,166,254,181,8,164,207,114,46,161,181,171,107,225,229,250,244,201,227,35,81,150,132,151,69,49,219,95,182,198,175,87,189,74,113,132,3,78,153,194,130,60,245,43,223,5,153,187,177,42,111,85,203,47,53,71,168,106,65,190,206,17,152,146,248,60,53,61,50,165,81,117,66,34,60,178,130,33,11,79,77,16,55,214,90,30,209,233,125,179,200,31,250,105,45,255,65,231,191,222,2,176,73,254,63,126,252,164,44,255,159,63,219,159,255,220,201,243,167,144,255,21,129,85,90,1,212,247,234,26,64,232,153,12,192,59,147,17,72,169,186,156,213,44,32,123,59,139,179,249,8,29,229,31,116,53,227,227,179,253,242,113,23,203,199,126,225,216,230,105,150,255,165,45,245,13,44,129,235,229,255,225,176,42,255,15,159,15,247,254,159,119,242,252,113,228,191,25,81,7,231,248,144,169,64,39,43,179,242,26,56,158,131,156,209,200,145,151,162,126,163,221,57,191,35,84,166,186,251,135,241,78,102,27,250,71,183,120,229,40,11,129,252,199,155,57,230,55,195,4,50,168,49,156,136,210,245,133,77,217,85,83,72,154,73,74,22,143,154,130,17,157,14,180,161,163,4,218,114,105,222,243,237,73,139,80,141,129,73,95,150,157,140,161,129,55,111,223,189,255,240,246,76,226,193,181,124,212,250,133,119,7,104,134,78,31,57,70,64,190,138,103,133,162,32,165,251,21,39,55,187,122,239,69,119,243,82,152,207,53,9,47,207,210,108,50,33,144,184,28,86,177,131,213,202,188,4,89,188,26,246,244,91,179,194,49,114,28,253,94,173,85,246,56,213,250,12,171,155,90,35,117,221,213,74,141,187,245,10,44,240,18,248,81,132,243,232,110,88,243,244,120,245,98,185,92,110,214,2,138,50,197,181,229,230,133,248,230,181,194,38,253,215,93,57,110,179,65,94,219,184,120,184,90,219,184,131,220,174,78,98,142,74,195,22,63,205,187,209,87,43,23,146,9,162,148,135,163,81,58,243,25,14,207,18,206,190,27,141,224,146,121,147,119,87,43,249,210,104,78,161,1,82,96,254,227,161,80,84,46,175,100,166,41,227,122,83,221,97,249,150,30,253,190,38,179,55,66,35,176,13,142,70,178,146,74,192,117,194,117,72,246,89,192,5,197,232,82,63,249,231,216,42,233,74,80,94,116,33,183,216,137,76,23,11,89,100,193,203,93,166,17,75,7,19,236,139,61,84,42,249,83,93,77,75,98,164,221,155,196,136,254,175,84,162,84,170,183,225,11,51,231,6,153,52,142,238,247,57,138,223,241,92,236,24,84,73,235,6,235,202,28,178,106,20,19,18,69,40,165,115,153,247,36,68,116,2,55,58,155,213,20,207,202,52,166,47,12,216,62,115,159,103,41,74,229,63,199,146,107,14,254,81,199,154,57,208,144,57,188,143,30,178,52,1,232,132,56,253,171,108,193,251,248,63,110,79,167,119,3,54,14,48,99,232,187,239,144,51,197,28,177,36,144,137,202,70,200,17,47,85,37,72,174,149,231,222,146,31,194,209,8,199,97,244,66,57,5,2,142,15,14,197,79,129,90,217,52,205,120,209,116,154,160,52,11,2,156,166,78,165,133,202,28,73,137,42,101,106,161,32,228,127,10,97,245,41,139,221,66,124,8,65,51,108,200,109,100,36,181,81,82,198,181,116,22,81,172,135,14,123,197,107,104,77,136,101,120,93,84,55,132,182,234,39,47,41,250,129,114,126,198,169,156,38,131,120,190,199,252,148,37,129,74,141,223,59,248,199,247,88,230,2,222,32,59,135,181,194,211,125,247,227,203,239,63,159,153,107,92,207,64,99,185,110,13,177,20,164,107,179,132,64,44,195,28,29,235,185,104,179,175,189,141,213,220,196,99,101,253,222,1,98,219,226,181,210,119,207,198,75,105,21,151,164,34,49,184,121,53,173,31,93,206,179,162,153,239,4,202,242,107,224,185,234,92,243,129,153,177,0,85,138,153,124,180,160,36,68,39,62,75,11,25,54,33,83,87,204,183,207,166,65,31,5,51,159,61,18,127,47,126,254,69,178,213,20,194,199,70,35,89,75,70,105,252,72,98,252,78,168,205,238,67,89,77,252,179,232,67,212,20,192,173,43,149,202,191,143,39,20,50,4,232,177,125,143,121,77,17,215,177,212,75,167,143,30,138,74,61,244,240,33,212,246,72,122,166,243,27,40,33,118,250,233,228,245,217,187,159,78,207,222,126,250,244,241,147,235,164,144,32,94,233,174,144,23,86,235,186,19,202,244,2,50,90,174,42,170,172,105,55,37,211,129,16,213,137,207,103,78,95,34,101,248,75,79,202,58,124,73,184,123,112,216,211,162,110,35,143,28,220,34,147,216,114,182,5,249,42,193,222,162,100,69,72,111,236,216,194,167,213,145,245,165,212,176,37,117,52,91,3,79,203,118,4,139,191,87,134,61,193,224,112,153,126,77,179,22,219,252,245,88,96,177,110,153,139,168,31,34,27,158,137,47,150,101,175,186,44,149,39,123,213,133,149,103,238,147,120,45,231,84,249,76,150,20,101,180,106,243,126,98,229,219,130,24,75,68,82,196,178,56,86,89,197,33,95,74,146,49,172,201,121,78,67,220,151,213,171,117,33,129,173,202,249,109,54,50,195,232,215,79,89,252,62,22,56,253,36,55,160,191,230,89,127,100,107,167,51,146,154,137,128,32,253,103,138,113,140,252,20,249,66,10,79,153,63,71,56,230,236,74,134,137,194,50,154,206,104,22,133,144,100,92,236,142,66,25,38,70,99,153,253,74,137,35,61,165,101,24,220,159,127,113,245,20,169,162,176,164,3,170,123,47,186,59,78,148,249,7,125,214,216,255,74,94,94,215,55,0,110,176,255,29,86,242,63,28,29,29,62,62,218,219,255,238,226,185,182,213,236,143,99,56,252,67,219,255,74,159,13,55,189,1,184,233,237,109,132,123,27,225,125,218,8,95,166,87,113,176,55,20,174,49,78,249,2,67,127,16,115,225,14,198,242,187,159,151,223,134,233,112,76,105,4,246,52,116,12,155,111,211,102,248,163,88,24,16,44,15,174,220,186,40,171,97,35,179,218,166,195,60,117,224,233,12,199,238,207,15,161,165,62,122,40,186,251,197,213,189,188,3,253,242,187,26,27,230,63,30,62,68,147,140,155,183,72,8,105,61,201,184,247,62,253,132,253,240,170,176,65,202,7,108,61,242,222,102,81,234,123,204,255,229,71,25,30,186,106,207,45,159,193,0,193,85,182,101,132,164,137,81,104,75,203,163,124,86,114,106,43,32,225,203,0,39,176,39,202,1,123,171,95,217,176,169,169,128,76,55,47,42,224,172,179,177,230,125,120,23,51,159,215,154,87,145,117,227,128,92,247,3,154,197,252,44,164,23,22,32,165,61,151,32,60,64,184,154,172,127,20,101,165,153,73,182,117,225,19,238,154,22,68,24,205,255,131,134,104,164,108,186,155,140,178,123,155,236,150,54,217,38,86,220,27,102,239,220,48,187,118,42,246,214,217,189,117,118,111,157,221,91,103,247,214,217,189,117,246,183,248,212,216,127,101,92,226,238,194,191,55,250,255,63,61,122,94,206,255,249,228,232,233,222,254,123,23,79,34,13,188,58,235,251,217,130,164,100,76,34,194,175,32,174,118,48,40,94,140,146,108,28,145,192,249,5,242,35,213,165,90,2,131,151,153,101,9,72,233,44,34,99,230,179,43,167,103,88,166,146,113,31,61,128,240,92,184,26,106,124,244,6,39,233,201,216,48,221,137,143,175,197,38,5,52,115,208,224,197,43,208,200,171,141,187,58,255,190,17,221,251,32,25,35,25,208,171,239,83,208,161,196,245,129,179,162,124,67,200,172,190,228,183,166,161,230,216,93,232,127,83,180,238,134,78,115,85,208,8,118,6,245,119,140,86,43,29,230,44,104,83,231,161,250,239,82,190,173,44,197,103,18,93,242,18,130,99,116,202,50,220,207,61,245,201,4,197,216,196,246,80,199,2,148,130,167,13,171,107,136,193,236,47,231,207,184,170,194,66,190,40,100,99,31,33,167,33,138,26,10,55,70,43,215,92,160,225,172,143,154,150,157,111,68,253,230,94,205,8,233,210,139,95,250,229,104,135,94,177,155,189,111,182,110,253,52,202,255,29,102,1,220,32,255,225,239,146,252,127,60,220,199,127,221,201,83,51,255,86,22,215,93,244,177,105,254,31,15,203,249,31,159,63,126,190,207,255,127,39,79,99,254,183,129,222,49,123,158,215,221,109,230,218,106,107,166,171,65,203,230,138,120,212,253,78,226,6,79,3,255,231,153,157,119,209,199,112,67,254,183,163,167,21,254,127,114,180,151,255,119,242,172,225,127,149,208,218,230,255,27,36,192,254,6,93,187,153,61,159,223,214,83,195,255,106,2,238,44,255,219,225,227,231,79,138,252,111,234,254,231,231,251,252,111,119,242,52,228,218,42,24,211,105,200,164,229,140,100,153,114,230,46,107,63,110,55,87,78,218,165,22,153,34,93,215,44,100,214,151,89,99,30,47,217,59,9,112,83,50,167,201,156,71,4,254,25,12,70,242,71,139,140,82,242,96,63,223,59,215,22,173,73,37,181,121,240,5,164,214,232,73,128,155,134,47,62,53,143,127,159,199,12,53,236,210,183,152,177,251,230,189,223,194,211,44,255,171,11,240,117,23,131,77,242,255,137,105,255,125,6,254,191,79,246,249,191,239,230,249,227,184,241,254,30,242,191,168,123,247,139,75,254,181,111,168,125,39,127,225,37,42,74,134,115,18,159,201,187,183,159,61,123,246,44,127,69,146,17,26,66,42,151,225,189,36,148,105,155,41,198,134,19,229,23,137,215,164,159,185,231,212,49,74,237,248,51,165,142,105,41,255,111,53,255,227,227,199,207,42,249,31,159,239,243,191,220,201,243,167,144,255,187,203,255,184,23,224,191,105,1,46,167,242,79,40,198,175,253,52,203,255,124,119,126,99,27,208,6,249,255,248,249,81,233,252,239,104,248,108,127,255,243,221,60,134,128,5,225,48,58,70,238,134,189,120,224,207,113,20,248,41,54,98,130,98,237,138,11,254,28,166,1,192,115,172,40,66,51,142,8,47,48,75,241,135,182,85,209,87,164,170,244,118,148,240,203,177,73,221,10,133,251,110,142,231,148,93,109,8,5,156,204,249,64,94,148,92,23,7,184,38,25,151,209,179,180,244,152,161,93,11,63,2,255,10,3,171,2,238,252,39,44,49,162,144,88,2,13,23,122,240,245,195,136,196,132,19,63,34,255,241,193,225,47,162,83,18,160,16,39,56,14,73,60,69,52,70,69,0,158,138,40,116,141,53,179,207,153,31,167,66,196,247,49,15,122,136,50,164,68,185,171,156,109,231,152,51,18,164,242,115,225,38,8,136,15,209,12,51,236,9,88,62,242,25,102,41,56,28,166,100,158,68,87,178,4,242,165,147,101,238,146,232,142,241,132,50,140,126,242,73,236,246,10,79,69,18,47,232,57,14,123,69,220,88,65,167,210,193,27,179,209,232,189,30,45,86,14,135,50,116,204,207,56,125,168,3,11,91,185,158,126,143,185,108,83,121,117,246,192,123,117,48,64,159,49,7,71,75,51,46,175,143,46,102,36,152,161,121,150,114,49,118,248,46,0,243,83,248,123,225,71,25,70,84,186,129,254,58,176,167,123,32,90,248,85,1,151,49,57,77,132,227,185,118,233,204,111,34,85,254,160,84,96,242,130,164,178,31,35,124,210,143,99,202,17,195,1,38,11,140,152,12,220,75,81,44,72,50,138,174,188,110,27,85,226,214,93,152,37,227,32,219,33,217,168,10,142,255,147,57,31,141,36,47,185,206,114,229,233,255,105,103,50,167,175,16,230,249,73,146,255,45,17,219,71,206,114,153,107,56,171,149,211,179,114,32,169,80,0,206,208,252,74,187,69,151,0,112,1,80,136,216,149,241,134,223,89,13,170,38,222,207,147,232,31,110,15,90,255,132,167,36,229,152,169,79,238,154,209,245,155,251,133,166,114,47,247,247,31,222,125,116,29,221,114,174,18,34,192,194,154,14,122,47,234,131,5,134,47,186,171,110,183,240,71,46,238,133,205,101,4,14,53,209,21,175,10,22,140,49,14,149,215,113,136,83,206,178,128,227,16,93,204,176,172,146,187,14,95,18,158,246,17,129,203,118,25,14,232,124,142,227,80,86,149,60,207,103,120,174,36,3,4,43,52,178,243,27,209,13,189,18,188,188,170,147,137,213,85,67,144,239,10,216,164,78,64,150,34,140,234,188,187,165,123,183,20,30,235,130,75,170,224,150,135,97,24,170,229,91,53,47,107,203,120,32,247,74,62,228,27,43,253,91,197,92,149,38,123,219,245,127,163,254,55,187,249,17,224,38,255,159,231,71,229,253,255,240,201,179,189,255,239,157,60,247,166,189,125,147,48,127,58,247,33,158,160,154,64,65,166,59,208,199,113,59,82,143,130,200,79,83,180,249,176,41,87,112,11,62,31,33,233,252,108,233,17,47,147,68,200,12,249,101,164,34,93,44,117,132,46,48,99,36,196,192,166,32,247,10,241,86,124,91,189,216,165,160,19,165,218,207,255,122,254,151,231,147,55,149,0,155,246,127,207,30,31,150,249,255,249,211,253,253,47,119,242,252,65,118,111,122,15,181,105,3,118,115,33,98,168,211,245,185,55,14,214,68,144,222,107,246,13,233,159,127,205,220,23,165,124,162,245,193,182,66,61,150,186,82,109,54,15,83,31,135,93,150,74,122,0,219,52,241,119,31,217,5,101,114,5,209,169,248,247,19,246,67,204,190,171,73,120,240,143,135,136,193,199,126,67,213,127,51,194,173,170,69,174,129,71,232,2,62,74,245,111,183,57,99,53,48,231,159,179,32,144,152,19,58,154,14,38,89,159,161,227,247,131,241,10,82,31,137,141,6,144,225,253,98,245,254,233,184,130,184,135,122,147,254,251,34,213,27,99,174,9,103,45,80,246,200,68,89,45,173,37,209,85,142,19,1,1,158,227,152,23,1,180,210,0,38,54,159,213,189,246,20,204,39,95,28,51,215,194,26,92,20,107,64,53,129,197,125,169,112,55,122,54,235,127,55,223,0,110,210,255,14,135,229,251,255,134,207,246,241,63,119,243,252,14,245,191,134,141,227,53,83,215,221,186,70,152,239,58,27,196,165,185,183,108,147,216,196,222,114,174,215,55,149,85,247,218,26,167,81,255,122,58,167,142,10,189,113,198,53,99,213,249,61,234,150,197,102,255,26,25,218,126,27,99,95,171,229,109,26,223,93,205,237,45,233,91,181,195,107,57,134,219,215,124,42,208,213,228,15,90,189,248,189,107,42,251,231,54,158,146,254,55,165,131,96,30,22,9,108,73,236,77,233,237,218,255,14,135,71,207,32,254,103,248,248,232,201,243,199,135,207,165,255,199,222,254,119,39,143,216,69,74,85,75,158,201,147,20,81,70,166,36,246,163,232,10,77,113,140,153,207,113,136,198,87,114,243,56,165,7,193,60,140,72,12,210,192,19,187,169,215,242,247,191,48,75,9,141,133,126,5,39,142,112,22,24,209,0,170,251,28,253,170,246,156,6,129,253,10,37,63,101,49,226,144,162,136,68,88,116,132,47,113,144,113,177,76,252,58,165,136,101,49,170,210,228,175,250,212,82,181,170,46,160,164,236,202,235,38,230,128,64,195,123,16,82,241,67,123,184,120,111,224,167,146,99,15,166,140,102,73,254,237,251,252,151,250,188,144,3,251,156,31,139,123,255,178,222,20,142,142,11,38,51,206,129,87,157,76,108,162,127,228,42,239,148,158,72,5,79,126,55,212,92,93,4,210,154,193,121,196,71,200,235,152,122,83,122,166,199,100,104,101,69,75,199,200,203,107,231,87,220,204,19,202,56,114,187,29,72,52,229,44,151,6,18,86,171,193,114,89,140,123,181,26,168,201,93,46,237,225,174,86,78,183,115,237,186,106,206,110,212,68,68,167,78,183,115,6,250,189,57,141,208,134,57,119,186,149,9,137,56,102,131,16,143,179,105,68,167,213,25,132,49,37,227,242,142,225,133,99,162,20,10,21,235,164,247,30,208,153,254,175,152,237,78,103,185,84,126,1,162,17,79,108,43,116,121,35,21,72,225,118,17,135,24,28,47,148,255,72,125,170,234,116,1,71,189,175,253,57,142,94,251,41,20,211,85,60,181,131,42,78,166,14,74,182,102,221,71,177,9,200,235,150,141,207,154,248,44,69,165,174,237,210,190,161,110,187,208,96,150,174,221,25,28,200,252,213,176,119,132,70,79,206,167,13,237,158,156,79,223,0,63,147,69,137,47,106,10,111,230,20,163,191,58,86,81,64,73,240,43,64,21,35,104,3,85,81,186,5,88,69,143,141,96,105,183,27,99,8,5,149,202,61,86,167,60,87,199,200,133,60,183,19,228,36,99,239,111,169,83,222,151,27,133,191,70,126,202,191,226,75,65,221,95,11,207,190,98,143,158,39,222,169,235,102,74,39,89,20,113,241,203,252,242,0,164,215,27,156,6,140,36,156,178,222,134,177,21,120,104,30,155,34,174,118,99,147,133,175,51,182,162,155,242,216,212,151,245,99,19,67,155,100,113,0,41,243,192,131,200,102,234,213,106,185,212,60,184,90,129,195,90,71,230,149,29,29,163,100,236,125,192,23,181,181,228,254,16,146,153,186,221,78,71,165,103,249,55,225,179,83,184,214,217,117,72,50,26,12,138,187,157,151,75,63,12,209,127,13,135,67,37,127,86,43,167,215,183,171,234,197,201,5,231,41,123,245,82,197,123,221,78,192,97,209,3,155,201,43,63,56,23,18,55,14,117,34,234,94,247,250,57,213,5,226,7,3,244,86,90,173,17,157,160,44,21,197,125,52,38,114,57,39,52,246,35,148,230,13,41,224,187,29,249,170,143,48,131,200,2,64,161,103,161,54,224,151,189,110,135,76,160,200,95,143,81,76,34,129,236,78,68,167,222,59,159,251,209,196,117,48,99,35,244,183,133,3,237,244,186,157,85,183,51,161,12,17,209,228,240,5,34,232,59,244,244,5,34,223,126,11,53,85,91,163,99,5,144,247,25,199,161,251,80,246,170,72,127,181,90,174,122,47,202,125,174,237,84,244,186,234,86,91,127,29,209,20,67,23,213,6,91,12,66,20,99,105,210,47,181,250,9,7,11,183,87,140,230,248,24,17,234,189,253,248,78,2,58,102,216,63,71,18,168,26,228,109,28,8,20,120,35,150,222,137,235,192,52,34,213,179,118,82,28,161,191,125,43,234,176,52,1,96,91,88,67,74,116,146,165,66,142,210,137,162,134,131,148,132,184,160,145,63,36,113,212,76,36,144,199,203,56,212,19,186,245,96,204,153,82,153,119,214,204,84,11,163,78,211,52,201,243,132,107,78,83,31,213,224,240,154,83,7,44,129,147,232,234,58,76,177,35,158,80,49,57,13,152,6,123,142,201,21,77,56,205,98,159,93,21,226,208,30,213,237,98,210,26,13,1,176,32,39,61,106,24,141,90,26,33,81,117,241,119,241,151,92,47,231,210,247,123,9,195,253,17,178,248,90,222,209,19,26,69,244,66,172,1,98,211,39,79,244,212,129,166,88,52,37,41,122,221,78,48,153,230,120,128,143,162,45,229,208,13,191,77,23,111,200,148,80,135,130,196,143,73,224,170,108,194,69,26,225,17,114,208,183,162,172,188,209,212,237,73,140,168,118,249,247,16,129,166,58,11,38,211,158,41,213,117,161,44,129,79,21,49,160,186,76,69,9,229,111,191,166,207,223,241,238,66,144,116,91,237,168,150,96,126,63,201,21,127,7,79,213,254,55,165,222,156,134,187,201,252,43,159,13,231,191,71,143,159,60,181,237,127,135,207,158,60,222,199,255,222,201,99,30,195,54,90,164,52,163,54,220,197,225,229,133,111,100,107,51,236,99,114,223,44,138,200,144,146,237,237,98,31,245,181,43,205,251,106,252,5,121,223,211,159,104,168,59,153,211,48,139,176,148,212,126,146,120,133,132,42,239,23,85,201,229,82,54,80,218,0,78,169,252,162,204,132,226,149,196,12,75,130,144,48,107,88,58,255,174,9,116,241,81,215,56,182,11,148,193,177,75,38,185,9,203,26,182,62,181,149,34,54,36,108,181,66,199,255,64,222,32,229,217,120,96,188,237,154,135,226,231,125,244,96,161,115,52,75,35,24,156,162,235,110,23,112,127,144,101,68,91,88,190,134,110,76,57,114,103,126,154,48,60,33,151,234,86,52,142,131,153,54,250,201,36,61,139,35,81,181,215,67,70,124,111,125,93,32,33,171,178,172,185,69,69,89,91,199,63,111,85,253,130,196,120,154,209,109,91,144,105,169,188,128,206,7,83,26,249,241,116,160,37,111,221,176,177,64,172,217,107,136,23,41,14,100,157,224,96,138,227,131,20,7,139,193,226,104,176,240,35,18,250,28,59,189,235,181,80,95,189,12,61,220,251,145,131,60,112,208,131,243,30,100,226,54,168,106,81,38,168,133,229,30,85,250,83,209,61,156,32,228,172,34,72,31,26,253,146,17,38,207,27,219,152,124,37,195,89,45,89,93,223,183,144,253,13,63,213,245,127,71,135,126,198,179,105,253,127,254,228,168,188,254,63,27,238,243,255,221,201,115,119,135,99,160,46,20,229,140,133,93,136,2,202,145,247,129,126,182,74,25,57,37,74,245,143,145,163,138,58,168,180,248,182,83,104,110,95,203,48,15,33,187,198,105,156,26,176,16,190,60,137,208,3,239,228,124,122,244,47,33,133,191,23,45,234,243,165,193,35,116,214,238,208,78,157,119,41,65,78,104,92,115,134,135,30,13,180,149,91,225,169,179,93,235,197,105,90,205,249,224,118,77,49,28,208,5,102,87,181,77,221,227,89,37,28,52,162,252,30,131,6,165,12,33,180,238,236,48,87,208,156,34,29,138,121,115,129,172,170,233,83,29,26,26,23,8,228,215,42,231,228,107,228,228,233,214,36,107,48,115,234,212,24,83,210,220,244,144,27,73,220,158,2,173,133,253,192,226,192,173,45,8,29,147,115,115,187,128,85,165,64,169,167,163,158,155,236,2,150,4,88,173,220,84,67,233,58,230,17,132,198,157,137,167,3,35,59,164,74,148,163,203,65,114,28,163,108,241,91,195,124,96,95,0,97,223,67,161,112,147,207,231,134,202,82,54,56,61,105,139,43,15,243,107,22,115,194,35,188,90,189,159,39,17,88,231,150,75,45,79,76,11,179,156,244,117,231,2,174,54,215,109,82,126,170,235,191,80,143,119,107,3,216,20,255,251,236,249,97,105,253,127,126,116,180,191,255,253,78,158,155,111,216,127,3,107,109,174,69,212,203,236,124,183,222,44,177,27,55,248,5,107,111,218,226,255,62,247,52,245,252,47,247,141,187,218,3,172,231,255,167,79,135,21,251,223,243,39,251,252,79,119,243,12,6,232,53,13,113,173,167,223,160,189,199,31,122,243,17,125,248,120,138,222,190,121,127,10,78,125,50,207,200,72,208,48,184,20,76,136,88,215,238,210,25,239,206,246,27,155,68,224,26,159,191,175,83,154,156,79,243,114,205,122,223,58,181,79,151,72,214,56,30,170,175,224,97,153,127,134,95,183,44,166,107,124,21,75,233,193,205,106,61,233,178,99,98,165,148,77,82,110,164,228,153,179,0,19,46,204,206,103,29,95,146,148,127,122,251,249,116,146,69,63,156,158,158,124,202,228,120,173,82,58,86,167,238,188,204,32,1,85,76,108,72,202,231,93,37,245,79,138,125,153,195,82,117,254,242,228,253,251,120,66,61,112,147,137,97,176,189,226,102,53,75,119,172,133,89,94,202,94,234,167,148,231,92,117,77,25,0,89,117,186,41,78,59,75,113,23,37,0,44,148,202,142,203,221,24,61,27,63,141,63,53,53,44,151,200,152,93,219,165,242,43,18,147,155,51,141,73,18,107,220,48,205,189,179,163,66,38,196,62,111,50,231,78,23,246,14,91,248,134,138,141,95,157,59,232,78,154,25,204,56,79,100,91,198,134,196,141,177,193,141,50,147,85,175,252,22,106,86,222,78,101,89,133,248,45,224,11,104,136,131,129,22,189,224,205,213,60,110,123,126,53,232,224,153,215,8,203,45,128,210,169,161,51,50,105,96,15,85,230,166,19,198,112,202,39,89,84,237,252,166,13,171,251,46,118,210,150,246,161,222,73,91,98,54,28,11,191,22,247,239,106,248,208,154,83,150,23,200,186,184,162,88,175,36,113,237,170,115,105,102,106,236,92,138,117,203,159,27,25,116,159,111,33,160,43,79,69,140,202,34,13,110,223,168,202,69,246,173,144,66,31,250,124,250,242,211,41,58,110,247,32,149,117,72,45,75,232,13,158,64,114,54,177,174,182,109,65,244,103,30,228,53,45,119,229,243,221,170,125,166,157,245,231,171,109,251,177,181,176,250,229,122,253,10,123,205,229,173,166,223,98,77,171,95,188,196,252,180,180,58,161,80,76,5,78,117,50,62,175,11,14,194,109,107,147,152,99,54,129,243,50,41,115,214,160,192,242,75,206,245,190,53,134,182,82,148,47,248,102,145,201,149,233,201,124,137,44,239,253,170,47,179,225,127,173,28,167,205,117,161,28,8,220,216,133,225,245,223,182,143,206,114,169,20,205,31,177,31,146,120,250,26,146,8,114,65,164,114,126,114,199,32,177,169,128,101,164,102,185,168,35,149,188,136,225,91,84,59,99,103,102,17,73,91,61,132,25,163,144,232,79,66,119,202,124,18,25,224,41,232,106,1,50,239,202,49,1,108,208,202,44,0,31,149,156,245,250,245,68,118,187,32,219,30,132,58,98,213,123,173,35,87,25,254,130,202,128,246,80,14,187,36,21,1,59,64,212,187,38,72,109,126,130,196,177,69,93,163,107,90,235,136,151,93,242,208,109,243,79,183,172,115,150,185,64,200,64,165,98,150,233,79,126,90,173,228,233,65,75,97,102,81,222,217,15,112,223,9,115,211,5,43,164,220,114,213,71,181,116,163,157,130,197,216,56,102,239,178,56,232,33,215,170,167,41,6,38,90,208,217,232,184,198,129,181,219,145,203,125,154,59,125,78,92,134,191,200,35,142,178,95,39,44,212,42,199,75,76,34,168,2,47,37,53,201,43,91,4,44,208,78,22,7,141,68,63,166,225,149,57,204,70,224,59,186,191,116,193,188,122,161,83,197,108,175,198,119,87,117,234,85,228,130,244,7,69,230,253,219,77,154,213,96,128,166,24,210,221,160,9,163,115,49,53,240,94,20,122,227,115,95,12,59,224,151,222,191,252,40,195,238,20,68,169,28,244,255,224,171,31,32,17,64,207,115,31,193,7,245,51,159,157,227,188,21,193,29,53,96,106,16,13,246,93,248,12,177,52,49,17,41,219,211,222,238,199,72,205,174,162,147,28,21,125,99,178,106,29,120,203,179,220,105,171,125,170,116,207,2,44,78,17,244,39,56,42,85,239,240,60,225,144,85,25,25,227,77,19,116,44,190,106,224,81,65,169,90,2,46,43,2,75,131,8,131,141,73,212,53,44,208,187,225,68,182,176,57,81,249,156,43,206,147,220,159,175,21,38,122,214,136,15,133,37,208,229,98,124,225,214,206,114,37,22,226,19,14,22,63,165,83,119,94,58,177,210,9,151,196,59,53,245,138,91,216,226,186,220,50,223,116,182,86,93,48,151,18,204,156,70,237,85,240,230,32,237,0,30,189,200,193,78,8,199,159,197,139,194,12,88,85,128,85,153,151,113,8,113,34,48,93,148,87,203,31,24,21,196,44,65,163,229,169,23,133,154,213,220,26,13,196,210,115,77,229,71,131,174,80,11,49,50,101,101,65,145,228,154,205,99,101,116,70,115,250,221,53,155,5,28,168,215,50,42,4,213,104,98,82,188,215,53,101,49,151,80,74,154,240,182,110,254,145,76,180,173,112,87,105,82,202,121,19,151,32,44,220,75,80,197,182,233,168,39,103,96,142,26,144,149,175,190,192,1,151,10,6,8,109,146,236,220,45,59,248,53,204,206,205,0,204,231,116,247,128,234,249,190,62,128,155,168,68,129,214,86,98,230,176,111,146,153,122,105,179,5,231,188,88,75,106,54,186,133,55,65,141,33,124,11,117,185,216,157,175,213,54,209,26,117,19,245,138,19,228,223,185,210,93,242,163,9,164,201,95,230,225,106,60,13,48,15,163,116,21,61,196,87,52,188,146,183,121,176,226,69,203,165,199,36,81,213,251,137,207,103,203,165,142,2,22,194,72,247,247,19,132,232,172,86,35,243,165,40,126,58,79,34,45,244,111,3,6,41,224,150,218,95,201,189,133,62,122,232,71,200,61,226,206,113,10,81,115,202,216,43,13,209,63,201,151,61,83,67,18,138,35,28,21,170,26,117,74,108,199,208,32,107,102,13,57,143,28,67,183,187,84,134,101,21,200,167,222,62,188,244,150,203,130,153,26,102,191,99,4,60,221,42,154,68,107,110,15,169,59,58,150,57,152,142,65,19,22,104,78,183,222,251,194,40,45,89,201,164,227,226,205,61,18,242,45,0,81,165,228,221,119,178,75,82,206,23,206,6,82,46,160,191,33,45,91,36,80,79,204,183,129,41,179,227,205,84,109,2,233,72,221,74,71,27,214,255,219,104,42,150,107,220,153,178,172,139,149,3,133,249,242,129,38,148,105,61,174,116,109,140,215,21,187,224,182,77,30,231,218,160,241,114,169,148,223,220,235,112,132,172,35,158,157,187,69,90,174,155,91,122,69,214,212,21,136,85,215,114,171,189,235,41,92,182,235,186,117,218,88,237,126,203,141,73,212,235,245,45,109,222,62,3,48,96,147,111,100,87,35,189,69,253,128,47,228,251,55,36,77,124,30,204,48,115,141,6,13,21,95,202,154,116,132,126,254,69,223,223,2,111,150,214,224,165,82,224,206,49,155,98,150,4,182,150,101,254,184,236,213,156,233,223,80,173,170,28,241,111,210,230,172,10,214,47,241,40,154,90,46,189,119,89,20,93,253,159,204,143,200,132,224,240,245,188,152,57,243,121,151,197,193,232,70,198,139,106,155,203,37,153,172,213,167,192,111,190,211,185,237,163,16,187,143,219,82,43,203,163,207,39,114,82,158,0,152,210,202,180,88,188,104,62,175,8,220,1,7,212,251,72,47,35,234,101,117,226,171,4,125,29,45,183,177,213,198,47,5,209,193,113,112,117,212,181,100,103,62,239,227,36,227,35,36,173,184,189,218,5,211,216,74,213,108,203,208,106,125,7,210,32,57,146,29,164,139,160,133,209,123,27,187,241,186,174,145,97,148,90,4,183,102,85,94,215,253,6,228,252,112,122,122,34,133,226,200,90,112,181,154,182,97,242,78,124,206,49,139,71,249,180,189,141,39,148,73,71,255,26,237,206,233,173,111,78,44,239,35,101,29,175,85,218,215,17,169,253,220,130,2,190,108,211,119,237,26,187,254,137,73,212,182,97,177,0,175,71,161,169,41,213,160,210,80,26,219,3,168,159,219,208,3,91,33,213,194,129,84,107,183,131,188,29,138,173,110,214,163,122,205,167,165,149,215,183,85,85,251,176,165,161,96,131,95,161,212,118,141,242,107,181,42,249,203,84,137,148,46,133,211,160,78,45,50,245,159,90,135,198,138,222,179,206,145,241,26,26,78,199,238,209,62,15,226,230,121,144,241,200,206,55,41,67,157,42,98,215,246,54,109,215,91,65,240,245,125,148,39,95,41,82,187,86,195,204,105,72,65,18,212,204,76,191,137,224,154,137,13,85,169,173,56,216,31,12,208,150,193,97,136,169,242,134,163,14,236,58,183,14,50,43,109,184,250,40,93,52,108,215,106,86,92,181,144,155,145,91,26,128,218,67,161,186,61,31,244,88,142,244,210,216,147,73,131,38,115,238,125,150,89,17,101,42,191,74,179,57,62,164,134,49,202,51,58,245,140,243,239,86,135,163,172,116,55,41,226,20,78,66,75,3,133,51,226,124,172,45,135,234,25,123,216,190,246,5,44,28,215,115,189,225,231,95,172,230,213,134,76,232,158,45,132,205,29,236,16,238,108,123,176,219,221,226,14,118,138,90,233,107,216,24,155,79,189,100,171,43,121,27,219,201,154,229,82,145,131,208,58,39,17,14,184,39,126,125,156,148,119,6,203,85,141,186,169,102,186,169,110,225,5,208,187,137,108,220,66,10,8,6,41,120,181,94,38,172,17,5,13,140,44,169,103,215,236,220,186,57,185,234,200,74,233,130,245,209,182,6,162,221,226,79,90,142,82,19,143,168,86,168,154,46,106,166,207,169,244,9,62,216,244,160,55,120,226,103,17,71,255,140,137,190,220,10,135,101,31,225,205,205,236,200,37,216,20,8,95,145,58,27,189,190,163,48,84,202,204,145,233,110,243,68,191,214,184,33,229,111,165,23,149,212,55,63,110,175,52,152,155,234,75,215,74,111,200,108,103,158,81,126,184,102,222,236,6,217,95,151,78,123,247,231,154,181,153,184,183,58,222,252,13,102,235,110,116,20,238,214,122,10,151,221,190,175,127,31,145,60,185,72,193,77,160,134,196,122,182,203,172,114,184,218,218,111,215,60,208,135,87,169,247,1,95,184,142,144,73,214,232,84,114,85,18,52,184,230,32,146,130,219,143,1,168,211,43,57,154,233,141,93,243,69,68,127,252,65,223,120,166,235,252,160,115,135,187,223,54,42,182,27,232,110,188,192,205,1,106,63,150,91,26,101,141,15,140,157,43,200,116,141,81,235,242,219,15,111,238,110,85,126,251,225,77,222,233,221,133,7,233,94,183,11,75,146,194,225,142,194,146,182,205,56,179,238,116,214,72,159,95,142,224,81,73,148,101,210,228,53,110,142,102,19,117,238,141,27,34,121,80,171,13,214,93,4,243,220,250,246,84,70,11,109,27,204,83,231,145,121,163,88,6,116,237,8,150,62,162,9,79,145,231,121,42,193,182,10,78,71,46,75,147,138,11,162,244,194,219,20,224,130,182,140,19,106,21,196,84,59,162,38,216,55,47,67,178,203,205,193,58,91,140,101,183,232,191,171,33,180,12,56,106,37,44,224,138,79,229,37,4,109,40,121,163,198,38,75,90,38,246,186,136,92,169,74,188,54,211,244,151,171,26,96,2,254,126,254,197,66,159,0,120,225,51,212,226,134,17,164,162,95,68,51,213,89,216,88,123,217,93,55,146,101,17,103,219,96,101,212,174,69,173,48,187,148,208,141,52,62,213,170,172,233,192,196,91,238,235,161,202,124,54,190,73,154,27,193,127,87,133,167,211,237,131,4,246,149,141,0,161,154,196,11,183,4,158,217,109,67,124,93,205,26,247,39,138,178,219,77,144,157,27,212,250,154,87,166,235,186,250,119,179,16,221,160,150,183,58,5,72,85,24,153,12,145,234,118,102,109,66,199,186,29,33,127,102,240,3,153,81,100,16,192,53,67,199,69,248,150,42,116,140,30,26,197,150,171,110,7,110,35,58,206,81,240,111,194,103,178,75,112,103,168,237,183,175,186,236,117,59,43,201,53,162,7,1,10,61,71,99,74,163,188,191,190,120,115,140,102,229,24,55,184,245,227,175,244,92,94,247,209,176,111,169,154,15,213,32,72,172,193,69,129,31,139,141,202,24,35,206,252,56,157,96,198,112,168,79,80,84,119,78,175,184,246,69,182,32,24,1,29,11,124,23,111,218,6,153,1,90,230,41,88,110,32,249,3,160,236,117,68,99,172,220,96,228,93,56,162,94,136,39,152,169,82,39,25,127,229,7,231,186,204,60,157,246,186,157,121,58,85,213,5,69,125,58,121,45,136,210,109,58,10,53,43,248,81,132,177,97,14,190,142,9,185,210,222,203,36,129,227,174,220,101,177,190,75,204,212,253,86,133,47,99,35,108,121,73,189,195,168,43,43,79,53,92,251,232,194,40,245,25,51,226,71,228,63,144,140,85,204,140,43,113,90,121,127,242,170,39,175,194,0,86,29,29,163,185,127,142,221,210,186,221,71,195,62,138,112,236,6,158,40,214,251,86,252,13,127,153,149,143,145,159,36,56,14,93,253,166,143,100,121,207,243,54,148,43,74,9,237,118,180,150,172,214,11,134,181,208,212,93,59,38,147,202,108,26,71,81,83,69,129,174,13,205,61,132,11,139,14,109,127,172,88,112,159,140,37,85,34,251,135,34,126,52,55,187,116,58,234,208,67,20,207,29,164,84,131,189,66,44,93,35,76,182,211,121,36,3,67,31,21,28,92,235,148,221,41,236,62,221,142,118,195,50,57,186,56,154,9,180,104,127,31,47,232,57,54,130,99,33,166,84,99,80,204,109,57,81,104,141,253,69,222,51,85,19,147,90,54,154,53,155,8,119,184,164,237,110,7,80,99,236,186,183,165,247,186,208,23,154,125,91,121,190,23,214,183,33,172,187,234,246,196,194,187,9,228,165,181,149,51,60,159,86,86,140,69,141,131,81,165,57,175,240,250,65,199,141,78,70,118,34,239,245,114,121,115,23,6,94,138,134,235,171,154,35,20,178,122,185,172,185,170,175,216,227,154,157,154,126,67,178,102,245,246,56,123,17,185,247,245,176,114,67,93,224,153,123,183,34,100,64,74,222,242,152,251,205,78,98,150,108,54,15,220,215,103,48,144,33,61,237,163,201,37,156,58,154,188,91,201,74,87,191,121,169,59,13,233,152,1,170,102,181,60,196,150,225,47,213,116,212,117,99,104,108,105,221,125,151,117,13,213,228,82,184,52,86,45,43,76,190,102,201,82,69,242,160,247,218,72,122,40,98,222,180,216,24,72,223,62,68,94,25,113,42,169,160,74,49,221,29,43,56,190,56,86,145,81,236,117,18,192,140,103,238,148,195,146,203,187,189,198,22,172,209,138,111,246,69,147,109,91,172,145,137,219,135,195,23,246,46,25,14,223,208,234,46,2,226,101,147,149,128,248,18,222,141,64,178,6,62,40,133,154,219,145,230,55,130,108,19,254,5,108,229,40,115,67,177,108,228,187,166,64,243,6,182,91,23,104,222,68,67,215,31,116,91,226,19,224,238,76,178,220,55,22,215,252,181,237,73,225,205,79,236,222,126,120,179,191,63,233,143,251,84,243,191,43,141,250,108,119,41,224,55,220,255,240,252,232,233,99,59,255,251,209,240,240,217,254,254,199,59,121,214,230,99,55,18,131,127,88,119,197,195,86,9,194,213,206,163,253,141,73,70,214,231,101,145,175,154,80,43,159,168,145,77,179,114,67,165,254,235,189,120,223,211,126,125,157,206,150,241,38,58,240,51,239,191,200,43,218,169,104,83,101,205,42,175,4,165,29,66,237,93,92,119,221,165,66,31,100,214,91,168,161,253,12,172,4,182,77,153,105,59,197,194,1,87,11,13,30,161,79,120,234,179,48,194,105,138,232,4,205,232,5,220,167,60,33,17,78,145,207,48,10,201,130,132,56,236,219,72,67,36,69,126,116,225,95,165,8,238,153,146,247,73,233,180,244,202,127,99,3,222,107,111,19,189,111,215,210,100,236,109,225,93,186,29,6,245,149,10,240,93,175,192,160,0,135,197,50,124,49,195,49,82,142,242,18,213,223,29,163,161,198,47,208,78,36,166,219,44,49,172,217,109,200,59,131,12,85,185,222,157,171,91,118,128,26,60,66,111,47,113,144,1,152,36,133,76,5,2,222,32,99,76,104,14,17,165,73,31,49,107,204,23,51,204,103,152,33,194,5,93,168,241,162,241,21,82,78,180,170,9,73,14,11,63,202,48,74,196,242,18,202,209,66,5,193,83,69,13,77,78,219,56,229,42,214,133,187,42,31,120,39,58,14,164,7,153,203,109,132,201,6,123,104,155,107,170,27,14,43,235,188,118,15,234,15,30,107,93,111,15,126,195,110,181,162,144,4,191,2,84,49,130,54,80,21,165,91,128,85,244,184,238,106,31,152,84,99,8,198,241,108,189,215,148,205,228,192,215,198,205,4,158,99,22,150,183,78,200,83,222,66,134,244,10,145,149,199,222,214,117,99,185,91,27,159,170,103,202,235,7,87,32,162,121,112,138,186,218,13,78,22,190,206,224,138,110,42,131,83,159,90,13,238,186,9,157,119,231,164,109,73,199,38,79,101,41,168,154,201,163,135,134,42,135,201,118,110,188,157,193,0,189,34,161,228,22,26,251,145,242,253,16,112,166,1,142,125,70,40,74,24,13,112,154,138,119,17,157,146,0,185,66,4,51,60,193,12,199,1,70,52,142,174,250,40,137,176,16,74,115,26,146,201,21,242,83,20,99,28,226,176,231,117,59,19,117,118,117,214,175,201,186,233,170,211,107,200,166,122,140,8,245,222,126,124,87,62,199,150,231,205,53,89,84,173,195,40,40,35,179,178,166,133,205,195,173,158,22,246,218,181,181,186,145,35,250,189,79,172,229,139,245,155,154,81,99,118,242,204,137,245,179,212,114,214,55,204,212,13,88,112,131,223,252,109,206,95,145,106,243,86,230,143,136,105,27,190,64,4,125,135,158,190,64,228,219,111,205,3,230,29,49,144,201,195,205,94,253,235,38,96,151,254,252,141,222,3,77,169,142,215,249,230,215,184,230,223,247,86,249,15,249,172,181,255,156,113,156,242,155,27,129,214,219,127,142,158,61,125,242,172,100,255,57,60,122,252,120,111,255,185,139,231,15,120,31,95,131,165,96,147,89,168,121,7,184,3,3,88,11,243,23,160,115,18,107,11,197,216,79,177,248,33,154,166,25,184,15,66,7,39,62,159,245,236,219,160,115,43,141,17,68,35,95,28,92,207,74,115,231,166,184,109,45,113,141,118,184,173,204,112,21,43,28,196,168,11,153,71,226,169,211,45,110,35,191,217,229,114,187,188,89,14,57,83,194,103,217,216,11,232,124,48,165,145,31,79,7,115,26,156,15,166,84,252,227,116,59,102,1,161,102,240,96,198,6,48,166,201,21,8,121,38,102,175,141,181,81,242,222,154,11,179,154,46,195,90,150,110,52,223,210,224,167,104,54,160,243,185,255,25,39,190,188,150,52,183,218,21,246,185,175,80,188,135,28,195,113,203,233,217,105,153,91,82,224,150,4,216,206,215,93,22,43,141,35,31,70,249,131,211,119,106,4,151,115,230,20,61,169,129,58,133,37,107,151,141,203,113,22,141,215,6,76,162,7,201,33,26,173,191,177,17,74,29,129,158,187,225,46,200,175,8,174,250,60,3,23,125,29,194,55,165,163,220,116,58,165,66,195,70,156,132,87,165,47,130,220,167,56,70,7,33,240,43,248,105,29,167,60,27,15,150,203,7,201,161,188,249,31,196,233,106,117,38,10,123,83,138,14,148,96,59,22,101,142,86,43,116,144,226,104,114,102,190,61,20,111,15,228,245,181,77,237,121,234,126,228,110,229,18,253,194,98,217,130,240,246,230,200,189,57,114,111,142,188,59,115,100,110,84,108,37,227,97,11,125,138,83,126,182,217,192,224,114,244,72,233,13,222,41,56,163,216,89,157,165,9,66,104,96,150,255,158,220,146,47,87,93,105,145,224,62,227,232,130,17,209,12,200,55,105,127,240,186,157,128,51,184,214,89,174,242,222,7,124,33,54,235,140,70,17,102,46,239,117,59,42,118,131,179,200,123,71,98,146,206,220,94,23,206,128,154,221,109,204,144,189,209,49,74,198,162,217,159,104,112,190,201,55,218,21,221,128,187,151,70,64,185,209,22,237,213,184,196,173,107,87,89,107,182,108,87,121,20,171,118,73,76,89,136,89,1,162,114,47,125,164,176,250,218,143,162,62,26,22,37,139,78,155,74,194,188,189,189,76,112,0,55,167,227,153,191,32,148,121,202,133,168,45,250,189,183,255,123,242,246,245,169,91,202,208,170,58,123,25,95,185,189,62,50,127,245,196,63,167,100,142,83,152,230,185,247,134,130,143,20,207,88,188,38,58,66,187,165,183,73,64,219,237,72,111,211,230,73,46,160,6,51,214,26,248,58,151,85,0,25,254,98,39,194,213,182,57,176,116,65,36,214,8,98,158,106,111,97,176,35,178,58,50,129,147,67,98,121,56,173,178,180,58,80,112,5,45,166,77,99,145,115,92,140,69,154,88,61,5,42,3,123,149,236,208,162,137,220,111,216,122,221,71,105,175,106,90,7,20,156,183,69,166,225,172,6,245,170,168,179,113,181,253,160,192,17,77,218,141,161,11,109,148,172,17,87,54,65,54,119,165,167,164,108,178,180,109,150,106,46,218,96,97,13,196,245,248,85,175,154,219,150,150,71,89,90,209,234,251,248,163,152,59,123,14,181,235,119,91,130,217,68,252,105,13,237,219,119,222,89,243,89,144,126,83,128,144,73,249,21,194,151,170,142,35,141,251,221,78,39,104,75,118,77,116,111,11,205,50,217,107,212,6,189,174,61,43,107,208,172,122,150,104,174,44,123,89,76,56,18,75,233,53,109,239,37,151,253,214,34,216,94,205,133,122,255,202,15,206,197,6,61,14,149,0,117,123,189,110,71,200,22,194,176,247,129,68,174,140,211,49,95,82,174,222,75,48,196,8,27,15,3,0,99,77,215,90,118,59,2,53,31,51,158,100,28,97,63,152,33,18,139,63,197,126,110,142,57,102,200,13,102,56,56,71,220,251,145,78,39,136,66,201,62,98,89,140,126,157,82,137,193,131,197,175,2,37,29,89,166,33,53,168,181,96,10,209,57,66,144,202,14,110,209,172,63,177,128,79,157,122,84,8,208,173,67,66,83,158,213,86,41,206,187,242,123,31,91,159,120,141,25,246,207,53,173,151,16,166,200,81,250,159,220,18,182,210,68,96,11,128,214,104,83,99,80,66,169,22,67,165,168,186,181,65,117,123,5,244,15,167,128,238,213,202,189,90,121,63,106,101,30,72,209,168,89,54,79,219,154,232,240,29,169,161,91,169,92,185,103,131,69,32,178,157,234,192,38,205,68,81,80,197,164,94,223,42,17,197,90,157,75,211,69,71,6,123,51,83,7,150,211,166,230,237,14,116,238,34,222,68,67,85,62,134,191,45,221,121,175,212,253,1,149,186,26,229,172,34,83,138,209,241,25,190,174,2,182,59,253,171,110,44,117,186,215,222,248,247,167,209,189,54,27,255,238,73,247,218,137,38,86,210,126,182,86,205,54,43,72,107,141,15,133,122,4,178,110,103,38,148,109,109,40,45,140,40,27,20,61,115,73,151,107,231,141,13,41,219,88,82,234,52,189,182,10,3,235,175,193,249,122,207,66,67,99,128,65,223,208,80,183,27,205,226,118,205,69,235,22,107,123,53,43,45,213,233,45,173,104,229,165,250,86,85,31,213,203,245,244,159,77,22,155,63,178,209,102,173,122,80,76,136,88,224,215,171,10,133,127,219,182,46,50,42,19,95,179,222,32,211,5,173,87,29,140,180,111,150,246,96,95,203,81,40,48,155,151,224,154,59,148,228,10,44,154,20,122,145,45,6,237,5,88,15,170,102,249,69,250,14,253,58,1,120,35,67,7,180,188,197,2,187,189,103,52,36,112,45,165,110,201,181,63,93,64,59,239,215,223,210,168,174,20,145,255,108,22,148,181,196,81,146,149,18,167,16,70,232,179,105,90,132,14,106,136,106,48,96,64,91,69,68,241,177,38,75,178,113,37,138,0,1,208,241,243,47,149,62,193,253,81,230,187,37,241,52,127,13,0,170,127,243,151,23,126,204,223,50,38,115,56,66,243,69,59,131,1,58,253,248,230,227,8,189,12,67,57,102,193,64,169,103,128,33,100,216,89,31,113,208,6,165,27,143,132,172,104,133,123,159,178,216,229,220,19,96,245,101,82,220,58,14,214,143,160,239,198,193,155,133,242,140,209,214,23,50,201,37,17,106,177,210,115,238,9,124,120,64,35,250,135,204,195,227,22,43,124,79,252,203,185,167,177,85,189,141,137,123,111,5,40,245,210,211,22,102,54,0,90,233,58,6,113,170,59,208,23,10,245,141,94,237,219,68,87,229,81,255,85,95,155,244,6,227,228,237,151,204,143,92,64,68,62,168,52,41,161,90,72,252,107,67,45,166,104,74,185,1,183,177,12,152,125,54,64,189,210,23,252,52,101,235,248,29,133,46,84,253,255,133,178,112,54,165,222,149,63,191,113,230,7,249,108,202,255,48,60,122,106,251,255,31,62,31,62,221,251,255,223,201,179,52,46,106,111,116,111,127,144,226,5,83,153,253,106,125,27,135,61,175,182,130,78,245,41,91,214,63,242,82,250,82,122,241,245,165,250,219,242,108,199,185,82,164,140,52,121,145,105,68,199,126,52,66,232,27,244,61,252,41,150,170,9,153,102,12,60,65,133,160,23,66,59,77,252,0,143,208,27,188,192,17,77,230,66,229,64,223,160,183,241,130,48,26,195,79,177,0,246,17,38,16,209,126,194,104,152,65,176,38,162,204,172,37,218,195,241,226,44,134,91,235,96,65,41,181,3,43,151,88,83,98,26,31,36,69,59,184,40,147,122,221,174,28,21,192,173,204,26,21,184,253,36,25,201,251,206,139,108,137,102,230,196,229,82,222,86,123,69,51,166,176,166,228,140,104,245,101,146,68,36,128,198,10,152,196,6,102,156,165,36,198,41,172,129,26,10,149,178,41,181,113,139,204,160,11,235,253,178,124,15,113,133,58,140,114,26,162,19,25,79,167,58,5,160,4,12,99,18,159,37,62,159,141,208,32,75,217,32,162,129,31,129,240,25,140,73,60,128,138,62,159,33,78,69,73,159,93,33,12,121,10,252,113,148,103,91,136,67,52,17,251,177,11,202,206,109,60,202,18,162,27,241,186,161,31,241,201,238,72,161,168,169,173,208,231,126,67,91,226,83,125,91,226,75,209,196,68,221,27,142,190,65,224,29,73,213,209,68,128,19,78,153,204,191,224,71,81,126,59,201,76,222,96,8,186,135,244,91,5,188,31,32,233,50,29,226,113,54,141,232,84,189,100,56,160,11,204,174,68,243,239,117,179,242,126,187,20,77,24,157,23,96,25,81,142,83,202,104,198,225,82,148,128,97,240,23,31,95,201,172,22,26,187,154,104,136,224,38,69,187,192,249,9,163,121,250,7,147,202,250,40,240,99,52,243,23,24,205,179,136,147,36,194,158,162,152,146,203,116,221,13,48,53,145,63,245,187,35,77,135,7,72,114,38,176,13,196,141,107,217,82,71,220,160,245,136,61,177,201,86,94,41,239,168,87,108,101,74,149,43,92,144,195,170,4,233,198,202,160,29,8,60,126,162,25,199,54,159,230,23,214,42,245,40,25,161,195,163,231,222,208,27,122,135,6,234,81,68,82,142,99,49,127,239,79,144,31,134,44,199,122,150,98,148,68,126,128,103,52,10,49,67,15,150,36,89,121,232,159,41,214,114,142,36,66,190,197,36,232,139,63,185,127,14,51,73,40,35,252,74,119,252,141,248,62,66,152,207,134,234,77,66,25,23,40,246,195,16,253,215,112,56,68,250,186,237,122,176,68,241,38,128,196,183,149,238,41,198,92,208,216,8,241,32,17,77,125,144,191,141,166,56,92,174,41,62,83,134,178,48,209,53,117,194,83,121,61,168,189,230,84,197,97,228,95,97,102,212,129,240,30,202,208,140,243,188,69,78,230,152,102,124,132,14,197,0,209,55,232,39,255,146,204,179,185,201,47,162,12,146,134,38,48,121,166,136,196,104,78,162,136,164,56,160,113,152,106,74,207,227,38,244,149,11,232,27,244,202,15,206,197,235,146,136,161,44,191,24,196,143,34,104,97,43,80,132,204,24,203,166,211,246,139,95,93,205,182,18,74,213,201,37,83,1,120,173,120,50,165,199,235,202,216,73,12,89,97,50,223,134,101,47,46,108,113,161,153,204,94,216,37,194,114,110,106,61,243,117,149,27,88,17,204,4,165,58,38,67,34,215,166,103,91,164,244,110,145,95,125,54,197,124,36,196,228,96,144,203,201,209,6,33,165,196,165,197,196,13,18,160,165,8,168,176,124,18,101,83,18,167,64,239,39,240,119,85,211,139,232,84,242,25,157,86,63,130,101,206,207,34,41,54,244,109,115,81,185,104,31,165,89,2,161,121,249,66,171,76,165,249,136,14,192,4,36,120,58,160,113,74,35,172,120,16,254,76,185,31,135,62,11,85,37,228,170,94,243,57,67,40,18,100,52,66,192,204,26,92,120,7,24,40,53,80,237,84,232,62,178,90,224,71,242,87,68,167,149,230,73,60,161,213,214,163,162,18,163,81,164,146,50,164,69,109,217,203,153,196,201,200,216,177,139,58,146,203,61,80,209,60,129,58,67,65,75,57,101,120,115,251,8,205,253,203,179,148,252,7,11,138,48,201,65,188,19,210,177,161,9,177,40,252,244,170,220,144,224,157,44,73,203,109,197,217,124,140,153,108,109,90,104,139,102,77,127,138,71,232,121,125,165,208,191,74,197,152,206,49,78,42,240,7,116,158,8,106,31,169,16,93,244,13,250,183,202,224,197,105,254,213,236,248,190,55,165,251,231,206,30,144,174,233,96,74,233,52,194,131,194,26,20,95,121,240,99,23,125,172,183,255,28,62,126,242,248,73,217,254,243,100,248,116,111,255,185,139,103,48,64,185,93,230,85,54,153,96,150,162,3,244,61,144,195,223,213,230,85,170,127,51,208,195,38,148,205,125,222,29,12,208,107,154,92,201,8,224,163,225,240,191,84,21,244,62,14,60,132,94,70,17,130,111,41,98,24,180,164,208,19,117,196,202,157,142,6,131,80,42,38,152,165,158,164,60,8,87,215,43,253,193,88,2,50,232,14,196,255,208,39,28,146,148,51,50,206,64,45,16,250,154,216,81,144,24,201,48,93,120,163,140,4,2,190,180,47,35,64,41,67,42,123,130,104,5,142,127,149,106,209,135,76,141,9,102,115,194,197,118,55,223,197,242,153,47,143,123,39,52,138,232,133,144,229,66,163,135,92,141,144,222,17,90,194,124,164,64,19,207,163,18,128,144,35,81,65,22,208,80,108,128,83,142,24,230,62,137,161,109,127,76,23,226,147,194,159,104,39,166,156,4,184,47,115,48,70,74,237,54,123,142,195,18,88,33,73,131,200,39,115,204,188,102,64,72,108,226,69,3,34,173,83,184,128,69,52,144,131,115,35,88,68,75,106,148,33,13,50,161,106,250,122,210,6,148,33,10,203,206,220,231,112,189,134,97,62,128,9,227,51,0,197,28,131,49,184,15,106,243,42,26,7,5,152,78,44,170,139,105,241,13,230,128,240,84,142,44,150,205,137,221,203,220,191,66,99,44,232,7,46,222,194,113,72,89,138,5,169,36,140,206,41,199,72,217,238,82,20,98,70,22,56,4,187,137,104,7,240,145,210,9,191,16,196,163,40,11,165,9,14,4,93,73,101,23,212,17,142,99,73,91,105,170,70,32,170,159,254,240,254,51,250,252,241,221,233,191,95,126,122,139,222,127,70,39,159,62,254,235,253,155,183,111,208,255,207,222,187,247,183,113,91,9,195,253,91,159,2,203,62,173,165,132,26,93,109,199,118,221,93,90,162,109,166,178,168,37,169,184,78,222,172,4,14,65,114,162,225,128,29,204,72,102,178,254,238,239,15,231,2,96,134,164,37,39,142,159,62,173,244,107,99,137,196,229,0,56,56,56,247,243,226,157,24,188,110,139,163,238,217,187,94,231,213,235,129,120,221,61,57,110,247,250,162,117,122,44,142,186,167,131,94,231,197,249,160,219,235,219,97,26,173,190,232,244,27,240,93,235,244,157,104,255,253,172,215,238,247,69,183,39,58,111,206,78,58,237,99,241,182,213,235,181,78,7,157,118,191,41,58,167,71,39,231,199,157,211,87,77,241,226,124,32,78,187,3,59,200,73,231,77,103,208,62,22,131,110,19,166,94,238,41,186,47,197,155,118,239,232,117,235,116,208,122,209,57,233,12,222,193,148,47,59,131,83,59,221,203,110,207,14,212,18,103,173,222,160,115,116,126,210,234,137,179,243,222,89,183,223,22,118,125,199,157,254,209,73,171,243,166,125,28,137,206,169,56,237,138,246,119,237,211,129,232,191,110,157,156,84,151,107,199,233,190,61,109,247,236,26,194,229,138,23,109,113,210,105,189,56,105,219,233,96,181,199,157,94,251,104,96,151,229,127,59,234,28,183,79,7,173,147,38,20,52,62,107,31,117,90,39,77,209,254,123,251,205,217,73,171,247,174,73,195,246,219,255,125,222,62,29,116,90,39,226,184,245,166,245,170,221,23,155,183,239,206,89,175,123,116,222,107,191,177,176,119,95,138,254,249,139,254,160,51,56,31,180,197,171,110,247,24,182,189,223,238,125,215,57,106,247,159,137,147,110,31,54,238,188,223,6,96,142,91,131,22,76,127,214,235,190,236,12,250,207,236,239,47,206,251,29,216,194,206,233,160,221,235,157,159,13,58,221,211,45,241,186,251,182,253,93,187,39,142,90,231,253,246,49,236,117,247,212,174,25,113,167,221,237,189,179,67,219,253,128,211,104,138,183,175,219,131,215,237,158,221,94,216,181,150,221,142,254,160,215,57,26,132,205,186,61,49,232,246,96,97,126,189,226,180,253,234,164,243,170,125,122,212,182,13,186,118,160,183,157,126,123,75,180,122,157,190,109,208,129,201,197,219,214,59,209,61,135,181,219,67,59,239,183,225,184,94,86,209,185,9,167,43,58,47,69,235,248,187,142,133,159,218,159,117,251,253,14,161,15,108,223,209,107,218,253,104,99,195,44,178,66,66,50,31,160,252,7,141,103,62,243,12,61,11,204,144,60,219,216,208,115,212,50,152,169,204,231,23,78,202,181,221,145,10,160,129,97,88,142,163,183,42,77,255,150,233,27,40,220,99,26,207,184,111,16,242,255,92,52,104,10,204,162,18,233,124,226,217,31,43,238,154,157,43,59,132,101,133,230,67,63,198,79,242,90,134,163,196,122,22,213,128,173,53,214,37,8,40,169,52,38,163,170,59,173,108,1,192,214,90,178,0,119,129,250,109,204,107,227,154,232,225,79,49,14,115,49,207,21,165,65,122,117,246,194,110,219,206,142,184,108,101,139,75,32,118,50,1,42,45,100,62,76,138,220,82,127,67,213,140,240,169,195,215,30,31,89,49,195,178,81,66,166,58,155,32,25,150,118,184,243,222,9,190,134,35,8,170,31,42,3,196,21,20,1,122,204,154,74,30,149,70,97,90,199,39,33,210,100,8,0,16,157,55,44,172,90,218,107,55,113,167,204,236,63,162,149,45,208,233,199,240,243,97,31,44,59,148,30,139,178,72,210,164,88,120,29,184,37,215,114,132,239,145,76,93,162,229,17,165,19,54,12,160,29,213,2,204,96,181,223,75,200,51,178,247,84,156,217,89,129,147,64,0,164,219,136,36,19,71,95,127,29,5,15,252,75,173,197,88,107,241,92,68,81,244,140,63,181,131,203,108,225,254,182,44,179,29,245,101,174,103,155,99,173,183,220,55,81,228,94,177,100,44,54,109,195,115,152,117,160,55,255,108,91,110,137,95,184,65,165,245,135,26,220,251,183,192,253,173,188,150,119,6,92,60,183,191,69,118,148,91,193,77,204,230,75,173,35,64,190,42,180,56,188,109,131,0,5,237,158,213,151,225,214,113,112,203,58,206,22,197,212,63,156,126,154,151,90,111,130,131,139,223,114,92,197,230,86,253,20,96,73,171,87,100,155,116,112,65,199,237,254,81,175,115,54,232,246,182,158,250,53,249,3,170,140,194,227,84,150,114,120,203,82,94,233,96,21,176,140,167,207,197,159,231,195,232,165,214,191,68,81,244,193,125,39,179,133,243,165,3,154,131,101,69,67,0,234,174,155,14,176,112,133,194,15,25,126,90,155,250,67,125,80,156,53,58,207,102,50,55,83,153,14,52,98,197,93,103,132,103,106,170,224,86,187,123,24,90,135,230,117,154,112,147,164,169,253,130,20,78,150,39,179,131,60,128,27,139,36,85,206,19,3,162,193,184,76,211,8,190,176,36,244,129,144,1,53,178,148,138,121,82,60,2,98,210,145,20,100,233,2,196,5,32,42,101,154,46,196,63,184,28,23,246,7,162,44,199,5,177,150,144,152,232,193,206,131,128,149,229,105,154,160,146,82,116,244,141,177,214,209,80,230,0,224,251,157,69,244,115,3,215,180,72,84,138,99,3,107,15,201,149,236,183,132,60,246,195,111,251,221,83,251,239,243,231,207,159,243,206,217,207,128,59,87,198,177,205,218,162,43,145,118,116,138,44,13,81,226,92,77,202,84,2,199,189,220,9,24,112,229,9,116,83,168,217,80,141,70,158,84,147,140,36,51,59,64,64,76,199,0,252,229,127,89,240,47,197,205,52,137,167,254,81,9,55,35,226,59,16,202,66,203,207,183,125,202,28,37,224,139,113,166,114,163,179,16,159,208,225,75,140,147,220,20,23,244,76,238,61,91,250,222,30,14,127,189,191,76,96,132,8,199,108,192,34,26,79,69,99,21,74,85,65,140,16,164,70,51,232,14,192,156,202,153,29,226,47,8,192,95,195,239,45,48,181,175,235,16,117,240,40,234,155,143,155,152,24,113,163,210,116,27,248,12,64,225,169,52,66,138,184,52,133,158,57,28,169,158,110,19,95,229,218,145,227,93,10,38,178,39,154,77,132,196,243,4,254,0,240,135,143,116,170,211,145,161,76,255,110,54,139,239,140,10,246,133,182,95,19,38,216,17,96,40,119,236,232,107,205,11,250,161,198,3,69,199,164,159,254,241,135,31,183,158,254,182,243,169,14,88,57,34,88,147,29,97,47,218,223,219,55,141,202,254,51,108,246,193,251,101,3,156,2,91,22,115,119,114,69,226,57,96,18,236,103,153,37,255,40,85,186,16,201,72,101,133,165,14,31,227,119,112,176,53,172,84,36,6,32,41,34,198,130,204,77,23,72,200,66,164,74,154,2,251,235,76,137,198,78,67,196,83,153,203,184,80,121,4,116,0,8,144,81,19,176,211,208,212,231,189,147,7,70,204,101,49,245,66,60,28,63,142,180,138,182,177,136,236,86,177,41,45,115,133,29,46,237,80,107,183,248,114,11,33,129,33,204,84,151,233,200,34,151,93,128,136,101,166,179,4,52,222,150,67,131,209,54,85,52,137,154,118,105,128,116,141,168,97,113,59,211,133,144,113,172,230,5,248,218,219,150,216,188,147,137,185,93,48,106,25,160,34,100,105,74,105,193,159,231,42,214,179,121,146,218,217,8,3,73,131,33,211,20,214,97,156,146,102,129,195,41,240,22,22,9,48,149,164,24,2,196,166,170,219,122,12,140,142,120,173,111,20,68,211,90,188,61,239,157,24,186,10,244,56,224,96,38,158,170,153,18,151,211,162,152,95,54,241,95,115,217,4,115,185,166,111,155,112,114,177,204,4,114,230,0,185,81,133,40,231,66,34,221,167,42,233,224,240,2,224,206,228,220,56,210,9,186,122,198,78,95,12,196,216,103,13,181,42,230,105,176,95,95,89,50,226,102,183,91,203,239,170,3,16,10,180,24,83,206,212,40,226,78,173,76,188,30,12,206,196,171,246,64,232,140,209,8,241,7,159,40,185,124,109,173,196,244,227,15,63,226,24,130,222,156,170,26,73,22,77,210,151,128,22,73,102,232,6,234,231,245,38,60,172,136,34,237,138,80,223,18,203,216,98,184,214,87,229,92,228,202,148,105,97,196,80,26,53,34,16,121,98,120,109,117,142,30,36,197,84,205,2,212,24,33,110,72,6,202,254,126,173,147,145,101,96,184,63,78,1,104,156,171,177,206,85,147,91,219,65,100,145,12,81,166,200,148,26,193,113,12,149,152,179,174,146,7,177,226,38,168,61,161,5,32,95,36,54,207,141,18,148,161,51,100,33,240,80,101,38,39,110,17,16,233,0,58,68,28,5,138,125,242,169,158,234,66,61,165,162,43,36,216,72,0,137,174,14,85,96,73,23,66,94,203,36,5,191,39,194,108,61,30,39,113,34,211,128,12,89,198,42,87,16,232,210,132,167,4,139,179,216,129,64,215,5,182,91,135,126,67,53,73,50,240,172,176,76,0,209,144,101,26,28,94,218,62,32,159,33,13,94,49,181,108,73,245,146,136,77,82,192,169,217,188,88,16,182,110,137,25,40,21,135,180,41,0,12,112,30,174,54,13,190,96,78,143,102,212,76,102,69,18,27,55,59,81,82,11,224,69,153,167,200,25,224,112,111,44,50,15,149,144,84,151,232,35,130,46,145,66,84,190,210,108,116,126,224,142,182,40,148,33,124,7,222,226,159,217,107,247,243,253,172,179,255,204,147,47,102,255,121,188,251,232,81,221,254,115,240,248,240,222,254,243,37,126,238,237,63,247,246,159,123,251,207,189,253,231,222,254,115,111,255,249,231,182,255,80,21,130,70,157,85,65,74,123,193,145,138,115,178,171,172,107,14,252,30,55,250,28,70,165,207,99,16,154,39,159,213,32,244,155,12,94,243,4,12,94,112,191,231,9,136,150,34,181,79,195,246,141,130,23,98,228,242,44,163,55,112,38,90,103,29,12,56,24,203,216,153,91,220,7,44,6,26,237,172,73,35,43,235,54,234,60,58,249,192,154,6,62,238,51,39,196,27,184,79,166,140,167,182,31,197,26,52,12,215,0,185,82,139,27,157,143,80,67,129,219,14,190,108,77,49,196,240,253,5,149,230,28,67,102,0,120,114,33,28,194,194,205,94,196,77,210,7,56,221,138,144,118,250,56,87,133,170,75,43,168,151,117,9,40,64,135,106,132,158,207,53,61,44,224,255,188,16,210,237,21,245,98,181,52,177,44,163,36,155,24,144,82,23,110,143,96,165,122,166,138,196,190,99,52,16,228,52,200,113,108,187,115,173,179,14,238,18,190,168,110,155,220,30,5,175,164,123,188,156,93,162,48,42,29,71,162,175,148,99,201,226,84,151,163,144,27,179,66,224,206,72,153,100,146,237,76,82,109,12,177,17,240,66,91,102,198,10,226,133,125,230,50,157,234,201,34,242,250,182,121,194,250,182,193,71,21,83,137,241,91,216,20,73,22,167,37,40,144,24,103,109,75,28,7,121,13,31,102,226,186,61,160,29,82,46,174,136,164,69,175,67,246,144,84,204,131,245,201,69,153,121,169,16,34,170,237,104,185,154,99,68,12,214,19,117,67,128,136,72,58,197,12,234,152,74,224,149,101,81,200,120,138,231,84,1,180,50,88,151,240,1,83,209,139,231,226,192,13,198,170,5,167,17,7,174,38,4,54,18,157,177,23,96,155,200,213,177,158,36,208,202,93,206,228,79,58,223,166,241,34,123,78,238,175,203,166,0,109,160,184,220,139,246,118,47,35,86,84,67,35,7,66,98,72,81,137,108,114,83,36,5,91,107,64,219,241,179,202,181,235,170,178,34,201,157,102,132,236,8,137,65,109,64,211,235,118,0,170,96,138,10,159,5,35,133,199,15,112,234,178,72,147,12,242,1,164,250,134,103,36,204,224,121,50,93,4,115,249,9,178,165,49,157,182,252,90,229,164,4,208,78,65,17,235,204,64,220,73,129,60,233,141,149,8,2,149,155,152,170,92,133,138,145,129,159,12,203,200,77,213,76,162,153,230,7,214,101,96,75,223,234,199,77,123,237,158,238,236,24,53,187,86,185,165,197,91,226,198,142,140,167,80,217,34,116,243,197,33,44,197,136,101,97,41,106,93,187,228,248,242,234,25,74,86,233,95,171,38,142,145,233,108,187,214,55,18,47,116,49,173,205,136,84,219,222,127,203,169,163,110,53,39,140,128,93,177,252,51,234,94,225,232,28,117,229,113,12,106,162,188,2,57,150,185,2,106,64,91,61,213,70,101,21,245,31,115,223,98,158,202,172,190,203,75,152,3,47,10,197,142,131,86,112,249,168,117,128,42,193,117,71,74,15,55,71,101,208,243,242,250,47,149,251,242,87,190,34,116,153,136,50,142,149,44,202,92,69,215,123,151,145,120,169,243,42,80,70,236,194,146,247,16,7,13,22,240,137,37,13,50,84,124,149,34,241,189,202,117,189,51,192,3,6,75,22,81,198,58,247,74,238,60,129,7,40,109,194,17,190,106,249,5,153,96,171,60,9,228,157,122,46,14,153,188,244,89,44,69,213,56,71,116,172,121,135,253,83,200,148,151,41,130,243,247,16,52,36,37,136,16,85,110,76,60,23,15,121,234,14,144,119,84,222,50,212,240,2,253,240,38,121,159,100,63,254,240,99,149,222,218,15,197,204,254,215,18,200,71,33,29,39,225,154,248,71,111,157,225,184,185,62,126,225,248,203,199,207,54,160,178,12,19,113,183,44,3,198,122,44,90,61,102,62,38,32,217,252,162,81,191,224,81,11,30,29,247,156,80,193,145,245,111,16,88,159,24,94,76,40,20,26,4,131,158,20,86,114,17,232,60,221,123,99,169,95,94,170,38,89,129,161,161,64,131,147,146,100,0,24,106,157,186,65,124,141,203,224,161,25,144,57,128,160,161,232,143,181,224,96,70,172,16,158,195,53,240,96,203,53,0,209,48,33,68,15,239,244,142,250,189,93,255,136,222,134,35,149,35,90,139,35,199,42,78,101,14,225,197,85,182,150,172,4,137,199,227,165,135,121,48,85,158,141,217,8,73,14,235,94,70,56,58,90,179,2,150,196,61,126,201,210,53,1,38,22,184,174,186,70,197,173,221,142,152,100,83,149,39,5,114,214,206,138,132,156,248,182,61,36,116,113,136,177,10,51,116,191,153,38,5,9,60,246,160,231,243,36,155,52,151,149,55,168,130,33,84,32,124,113,43,97,150,40,120,234,147,194,189,176,14,40,28,195,173,82,231,201,36,201,100,234,14,132,225,108,75,203,190,102,153,166,85,218,23,63,155,128,250,95,135,215,156,130,160,4,60,164,100,17,190,78,12,153,117,182,136,192,19,91,96,84,193,143,195,50,220,4,42,14,225,224,141,42,59,151,1,155,28,194,5,231,78,109,155,244,236,20,83,251,159,66,229,89,117,80,212,60,86,14,38,66,143,55,34,208,36,189,241,166,229,10,130,101,153,217,165,197,81,91,71,61,152,89,246,40,54,79,75,228,251,127,200,181,46,126,252,225,71,132,41,25,211,1,50,203,88,119,135,179,164,143,9,26,16,220,143,120,116,200,56,141,174,189,99,6,159,70,43,142,149,49,148,92,42,180,241,239,236,136,87,170,32,223,156,145,202,211,133,133,185,117,116,98,165,87,21,23,222,137,72,228,243,216,182,109,197,233,38,254,67,245,164,182,40,55,146,17,155,173,56,173,120,159,9,186,1,98,147,193,155,39,145,61,170,173,104,162,236,235,211,216,185,222,219,249,133,237,253,207,191,250,234,195,211,9,140,221,8,124,75,62,172,242,35,169,173,219,20,58,183,15,222,245,254,210,218,251,248,85,8,215,29,151,242,44,244,13,227,173,146,168,116,207,85,172,243,209,242,246,28,203,66,110,210,191,203,163,218,79,63,121,135,246,171,59,244,209,173,169,224,12,32,75,53,28,49,68,29,43,65,58,183,58,14,185,93,218,207,136,246,207,79,138,143,126,224,144,87,235,139,56,24,85,112,46,240,64,115,80,81,118,41,139,216,9,187,13,88,186,203,52,215,114,125,149,65,46,89,195,79,170,10,34,20,32,7,24,251,150,163,171,88,230,146,93,238,184,231,14,61,19,18,160,149,151,180,162,203,72,180,106,68,155,92,85,117,14,46,172,158,156,80,104,41,88,44,210,20,52,0,10,101,1,53,30,83,117,51,30,54,66,148,186,100,2,134,116,157,168,17,189,59,203,79,133,159,204,172,120,32,110,193,231,255,251,183,120,255,238,183,120,165,11,237,169,46,148,152,234,155,213,178,97,64,185,81,32,34,105,244,242,122,239,210,62,60,151,215,251,151,81,213,165,235,210,210,216,75,22,63,51,146,188,44,230,89,206,199,75,231,73,17,8,64,18,253,185,82,9,7,10,243,194,126,242,115,229,158,112,112,220,176,223,227,219,142,239,193,74,143,187,47,124,201,220,145,217,229,63,21,50,78,141,187,122,246,77,116,119,45,180,15,213,214,229,81,241,255,33,244,179,43,253,213,56,232,228,8,64,144,59,233,198,2,213,145,103,102,152,57,252,136,140,1,174,66,217,54,249,96,16,30,90,57,231,78,216,134,99,88,148,179,231,91,153,200,126,240,239,228,25,241,239,241,179,198,255,131,60,173,242,29,76,99,240,219,124,65,110,169,255,190,183,251,104,175,94,255,253,241,254,222,189,255,199,151,248,185,247,255,184,247,255,184,247,255,184,247,255,184,247,255,184,247,255,248,210,254,31,22,127,202,98,170,243,167,226,74,101,133,206,254,203,63,6,98,243,111,240,145,248,78,230,35,185,69,119,232,109,171,119,218,57,125,245,84,96,168,25,166,85,242,124,114,98,2,175,233,246,223,207,218,189,206,27,64,13,244,136,54,194,148,32,47,136,66,35,89,33,235,23,141,142,239,143,216,148,87,18,8,137,123,24,143,136,27,218,2,167,255,161,18,234,125,161,50,75,182,174,19,73,96,24,251,236,57,144,128,240,252,100,201,173,180,195,78,114,57,227,184,29,57,178,220,248,145,30,169,87,172,12,32,25,5,101,78,83,140,18,124,228,32,181,145,65,161,177,214,158,181,14,218,54,215,101,225,2,111,17,22,71,134,74,200,86,117,244,245,215,46,15,223,109,156,158,149,11,76,161,36,104,108,245,88,140,148,76,217,81,28,53,168,242,198,219,139,32,120,193,25,69,17,6,183,11,65,194,78,116,179,7,211,22,249,218,163,134,211,232,153,66,187,103,32,139,71,112,188,112,34,56,144,23,160,45,109,31,177,223,200,246,68,101,219,255,231,180,245,166,221,64,75,35,40,80,139,169,202,28,137,191,177,127,208,179,50,78,229,68,52,182,183,255,207,47,182,203,135,11,93,22,16,167,50,151,134,94,3,28,118,217,51,105,255,35,158,73,17,111,224,167,56,4,185,78,183,123,6,225,137,2,42,154,192,99,233,19,61,123,112,35,209,173,103,157,103,148,247,234,241,254,81,85,251,118,144,113,202,97,0,175,196,27,203,190,163,198,86,204,229,0,25,123,73,15,246,201,222,9,210,234,242,119,96,182,6,1,115,233,187,185,44,226,41,90,175,200,144,70,166,85,76,70,56,159,202,166,24,170,66,218,119,60,143,125,32,4,198,37,53,160,197,246,94,163,41,26,121,188,223,136,68,135,149,50,206,46,139,242,50,68,180,201,36,75,147,12,50,163,89,212,165,193,192,196,234,192,34,153,152,160,0,99,24,90,143,90,153,80,153,229,250,70,171,175,120,226,239,38,25,52,240,104,30,24,188,248,126,27,87,118,15,84,7,129,155,19,233,54,111,236,61,82,239,231,105,18,39,150,2,66,254,76,103,89,143,245,108,38,179,209,182,93,27,221,48,114,120,24,169,64,47,73,119,141,99,234,241,107,184,184,100,44,54,148,126,55,18,104,172,177,127,60,32,197,65,224,24,230,45,64,222,92,6,16,95,144,99,22,184,114,132,246,60,23,2,154,170,139,66,95,56,8,106,78,60,30,84,95,55,141,174,240,170,149,174,56,53,223,47,176,170,190,76,82,117,236,192,199,251,230,114,93,226,38,39,148,10,184,2,157,165,59,234,90,229,139,98,138,21,11,48,28,111,33,240,154,225,78,211,0,176,39,114,62,87,80,7,67,20,122,174,161,20,131,76,209,225,168,41,140,198,58,40,182,61,233,98,160,185,17,67,136,98,130,144,119,72,53,7,39,142,115,24,145,20,161,175,4,189,99,147,82,230,50,43,84,168,250,246,39,96,220,9,49,62,130,30,57,136,39,76,84,106,159,42,43,32,52,237,18,237,230,234,114,50,37,171,39,154,214,10,21,79,33,28,48,93,248,9,157,229,170,26,159,116,147,228,44,64,194,182,36,160,39,212,185,42,104,128,24,80,15,194,197,4,191,171,248,198,229,74,206,216,137,3,160,91,121,92,24,66,155,141,82,10,25,211,153,178,144,216,127,114,233,227,150,236,27,236,215,73,126,75,104,35,132,184,188,153,206,23,66,22,66,103,177,189,41,46,110,80,122,207,49,170,169,209,12,92,34,216,214,152,204,146,84,230,233,2,208,110,6,161,72,154,80,63,126,96,192,221,100,123,219,217,72,49,11,33,226,24,236,55,59,156,84,193,224,227,55,10,92,6,113,121,21,2,82,113,150,241,49,105,122,236,14,210,34,170,229,91,12,139,134,107,246,145,28,17,111,228,130,86,86,83,82,86,46,237,170,254,30,201,236,221,125,24,94,222,59,61,36,193,141,229,183,132,191,188,240,62,45,7,207,54,136,230,6,188,32,179,76,107,169,240,50,227,180,134,222,82,67,34,184,80,107,194,7,248,86,180,172,205,10,9,5,223,55,112,142,140,42,92,42,89,120,40,50,20,137,172,122,159,144,151,153,41,100,81,26,28,232,103,149,107,188,111,137,149,97,237,94,195,37,231,64,75,231,120,112,35,23,85,23,41,203,225,58,86,137,69,92,118,25,195,206,112,240,149,167,3,149,193,243,220,206,88,248,91,91,123,22,128,53,229,37,130,86,36,207,45,39,109,155,217,151,0,199,102,197,50,205,40,29,1,24,166,106,230,94,128,152,28,80,237,61,8,221,85,209,35,102,229,187,55,84,142,184,150,217,92,230,6,158,102,219,223,173,23,183,9,105,15,151,188,241,169,56,240,192,85,158,219,123,192,46,85,216,8,243,32,192,121,194,214,7,103,177,234,245,224,154,39,129,87,207,48,41,102,210,92,129,222,7,243,219,168,145,32,79,49,31,174,188,244,210,82,222,214,40,56,62,240,181,30,38,197,77,98,148,104,232,188,97,199,164,196,56,206,121,226,37,142,44,84,86,206,42,16,150,73,86,60,58,244,48,92,56,24,130,135,174,191,200,98,92,179,133,231,194,193,19,77,177,200,65,57,115,19,96,201,149,151,237,214,224,188,215,190,56,237,158,182,197,115,177,251,172,242,233,89,175,59,232,30,92,116,65,140,109,157,48,115,247,129,102,235,133,174,86,86,24,73,85,144,175,7,50,47,108,248,188,16,150,154,208,172,108,32,73,82,118,4,117,118,51,162,123,228,178,52,74,44,34,234,124,65,247,13,24,103,208,116,101,186,224,161,56,0,191,17,53,44,143,216,136,162,6,208,20,157,33,104,217,8,187,0,30,225,52,77,32,231,67,37,228,208,232,180,44,148,216,52,186,201,3,22,12,91,12,214,44,145,38,0,144,73,70,106,37,112,91,145,128,88,127,158,5,110,167,52,225,112,96,160,49,202,114,39,133,206,113,250,198,255,215,136,168,13,55,37,251,35,44,51,49,222,55,215,133,188,103,222,253,6,107,12,122,47,42,123,203,19,93,186,105,97,255,233,41,134,103,23,47,162,199,81,43,172,229,74,94,137,84,230,19,229,248,32,123,155,102,246,209,138,167,101,118,101,220,174,128,161,121,105,28,240,19,127,95,144,228,199,94,97,144,70,218,75,93,150,245,129,155,2,51,133,0,98,189,62,216,142,92,193,6,219,147,75,85,1,233,26,178,202,75,169,32,51,115,36,208,222,139,108,143,125,4,253,62,251,199,155,39,30,105,133,79,55,63,216,222,231,58,120,168,45,211,16,240,11,60,224,234,87,131,94,107,158,136,120,116,45,70,137,185,194,243,172,83,149,138,25,111,201,144,215,12,28,127,29,57,65,89,24,144,144,168,160,76,45,148,11,75,217,76,209,100,69,109,120,7,44,114,160,184,109,156,59,155,81,121,193,49,245,48,56,12,41,193,19,133,196,123,108,148,232,140,199,154,235,36,115,76,28,81,25,62,121,89,39,116,224,39,92,40,82,27,227,205,112,3,161,46,26,168,182,204,56,152,33,236,78,215,218,121,140,249,113,103,210,37,22,227,225,28,160,8,33,132,138,204,83,25,131,176,54,87,113,34,211,138,39,4,39,27,115,28,117,170,245,21,15,150,38,87,234,41,255,33,196,127,253,23,34,204,133,155,228,2,38,217,60,109,189,105,111,133,68,43,112,236,112,85,48,124,50,54,184,11,142,157,119,254,27,5,139,47,86,108,113,55,10,95,84,218,217,164,168,106,79,48,33,7,58,244,89,156,111,189,105,87,31,68,108,70,49,254,116,67,125,134,19,168,197,66,220,36,238,151,69,120,230,238,193,197,27,15,196,109,57,9,13,165,113,27,238,158,238,202,150,68,2,46,134,71,46,64,217,196,208,44,76,158,16,62,119,118,179,153,26,37,18,174,53,154,72,120,55,152,124,51,172,181,83,22,155,197,180,244,233,207,151,112,193,56,223,65,123,201,2,16,98,61,3,124,116,121,21,172,16,134,210,27,200,210,114,52,162,212,37,238,104,71,186,28,166,106,251,191,4,57,126,50,117,157,201,43,101,207,167,204,44,214,164,11,127,77,61,17,180,120,237,47,163,61,37,126,150,64,118,52,30,3,1,245,86,34,179,140,99,56,191,250,171,240,210,39,166,194,167,0,116,126,213,123,8,219,93,247,205,128,253,77,178,144,80,68,243,97,52,13,21,11,73,225,86,97,130,11,177,179,179,254,78,184,80,186,11,19,235,185,10,174,7,24,149,50,229,4,91,139,157,180,255,208,148,221,31,80,175,80,241,230,135,1,209,29,150,134,227,39,23,188,183,23,86,178,47,146,184,76,101,46,64,137,22,9,209,34,162,66,108,184,189,143,160,33,68,187,205,34,92,119,109,13,162,81,91,68,195,30,180,23,252,125,206,44,152,203,10,91,185,131,11,230,68,15,50,34,53,176,147,254,118,250,43,140,118,37,59,65,253,80,253,35,150,140,239,124,25,32,183,135,169,92,122,239,231,219,244,247,32,112,254,117,236,194,136,176,25,20,26,56,155,11,160,8,182,136,30,116,166,255,137,177,20,97,92,82,198,126,153,77,74,57,81,6,145,24,115,249,53,49,186,197,15,51,114,150,193,25,56,94,217,163,234,100,164,95,114,67,52,87,174,144,40,30,15,22,38,40,26,97,172,130,91,164,156,233,50,3,30,192,162,135,131,30,46,6,172,26,88,11,14,255,97,5,3,209,1,45,168,176,20,136,58,200,108,192,105,112,172,105,237,184,6,203,60,62,52,119,119,135,86,147,20,9,23,12,96,91,170,229,92,128,212,87,55,154,120,173,164,32,190,81,23,83,168,127,43,13,160,58,123,238,2,87,157,100,215,58,118,209,137,172,202,14,216,148,144,140,75,208,20,170,184,12,226,102,112,213,86,136,134,55,7,163,38,81,89,165,179,42,35,1,250,53,193,250,181,26,119,250,191,181,123,244,191,24,62,5,82,64,83,252,175,189,84,255,139,235,1,55,75,78,188,195,52,173,206,25,213,111,37,139,50,85,17,129,152,27,179,122,12,102,125,156,58,130,34,82,80,25,101,183,140,226,82,249,82,133,99,162,240,233,144,39,34,143,240,213,60,17,93,134,81,147,99,3,252,20,1,83,158,235,121,78,47,157,30,143,141,66,119,124,158,193,227,0,189,91,117,253,130,139,146,224,248,157,170,68,85,223,132,87,252,173,197,2,187,104,223,254,2,100,64,40,189,241,92,236,61,66,201,173,166,222,17,129,38,231,222,245,235,95,236,103,141,255,87,221,22,244,155,230,248,168,255,215,222,222,254,254,193,65,205,255,107,247,241,227,123,255,175,47,242,115,239,255,117,239,255,117,239,255,117,239,255,117,239,255,117,239,255,245,207,237,255,37,196,11,78,20,224,116,129,75,79,23,230,43,17,195,5,116,232,203,236,39,185,16,175,166,106,38,111,100,209,20,223,170,241,88,28,43,153,161,114,20,168,145,137,194,216,49,52,68,24,39,151,3,239,203,73,107,144,174,5,249,90,199,186,196,236,1,161,69,45,194,139,129,9,41,131,47,216,121,172,200,101,102,82,96,175,209,60,128,78,81,114,149,45,213,14,197,148,198,74,176,72,63,67,169,2,114,239,186,54,57,165,224,77,10,195,206,1,91,209,198,39,57,52,253,106,31,35,207,51,126,246,122,25,117,75,191,239,113,151,204,77,61,204,16,145,232,172,241,9,185,147,226,248,66,101,114,152,170,11,153,171,76,250,236,75,27,21,71,23,58,96,182,235,120,163,63,212,70,156,131,51,132,138,165,101,88,114,7,199,54,228,188,192,72,195,137,206,147,98,58,51,98,164,179,7,5,170,28,70,37,136,173,67,173,11,83,228,18,2,179,35,7,58,77,113,49,6,59,100,255,172,221,62,246,174,90,75,246,116,76,84,140,230,168,58,142,245,85,81,87,39,225,122,54,156,237,37,41,196,92,230,224,255,20,90,233,170,99,252,114,155,75,0,139,144,62,200,158,139,138,72,103,205,9,239,202,186,201,112,180,95,86,152,101,157,1,69,4,166,163,21,150,67,8,99,242,12,90,145,43,181,210,69,136,17,118,255,25,26,139,237,45,107,140,181,110,52,93,226,255,70,83,168,34,142,200,210,121,234,253,45,96,223,102,222,28,237,40,201,42,127,167,145,2,27,93,22,47,2,7,183,78,54,82,239,149,43,100,50,47,135,105,18,251,49,157,63,18,18,36,55,0,112,107,192,210,85,102,34,39,58,24,228,162,50,223,222,238,234,9,111,148,188,186,219,116,100,189,126,169,115,98,198,182,65,92,128,216,254,100,66,10,11,157,165,139,72,28,107,206,71,188,2,58,59,99,13,54,111,97,79,83,81,232,249,54,150,5,13,9,112,72,166,43,131,214,81,134,208,9,18,88,160,191,94,208,184,157,149,179,122,7,149,149,51,110,253,176,210,154,242,133,213,59,112,252,34,228,161,168,92,7,149,142,150,70,103,71,28,204,60,17,98,160,69,248,46,229,117,240,185,45,190,241,94,52,176,92,229,173,7,38,244,150,244,15,131,28,106,204,125,230,159,203,64,40,161,99,123,167,75,96,137,141,28,43,200,50,54,67,187,75,98,216,47,10,167,226,247,101,42,115,176,24,229,101,86,36,46,57,87,37,125,181,175,62,65,43,54,104,85,82,21,232,18,180,234,194,123,158,46,236,131,77,14,132,190,98,113,161,117,90,245,186,228,84,51,164,197,114,185,102,188,10,235,73,37,5,72,37,63,76,72,92,124,19,231,174,65,78,22,150,181,231,55,18,120,4,206,77,184,210,253,147,95,213,189,253,85,132,173,154,76,133,255,250,36,98,182,113,43,38,225,249,144,219,236,221,145,238,81,117,232,122,211,76,153,66,141,24,255,15,62,233,182,96,98,24,94,110,155,39,237,129,254,224,151,170,106,18,239,190,41,100,94,16,241,230,76,65,38,185,86,209,170,198,42,27,17,89,70,207,172,247,174,113,181,117,117,226,229,27,117,176,164,236,172,129,234,182,235,2,75,144,115,170,26,159,128,38,83,122,92,223,9,109,63,188,24,169,56,117,183,214,129,244,6,247,100,25,150,199,140,182,56,179,30,59,181,137,40,228,132,243,113,69,162,183,226,83,184,191,228,170,2,98,45,223,37,242,251,3,195,32,31,124,142,217,236,217,222,6,174,50,236,212,230,6,167,70,51,185,224,132,97,133,208,215,42,79,229,60,116,214,225,246,191,255,193,214,206,169,58,49,239,148,59,165,39,207,216,245,136,214,131,87,4,88,68,151,249,107,105,207,188,255,229,242,214,176,159,215,36,185,86,25,57,24,201,133,203,212,229,206,10,28,70,87,60,241,14,68,190,215,187,64,46,86,95,17,198,142,192,213,27,24,176,28,125,69,61,218,36,5,184,174,88,166,49,87,177,158,100,201,207,10,3,49,32,173,214,50,27,112,158,193,211,60,207,85,161,70,148,61,169,12,63,187,32,14,243,185,120,242,196,82,82,132,224,40,77,192,73,202,242,145,232,16,194,53,99,28,36,89,232,89,234,115,45,17,98,85,160,9,26,66,129,117,176,157,191,95,69,62,253,203,3,126,14,238,48,60,103,184,130,198,253,194,62,108,224,3,235,92,201,118,237,131,227,206,9,170,56,129,199,162,51,144,117,209,248,101,196,141,74,114,108,49,77,236,134,131,119,118,174,164,209,25,181,30,188,59,107,95,28,119,207,95,156,180,217,219,141,62,124,121,210,109,13,152,22,179,5,87,124,159,76,190,151,19,118,72,141,132,56,85,19,100,71,249,6,23,242,74,137,189,93,172,65,16,9,113,110,20,14,216,239,156,14,30,29,138,196,249,47,101,220,53,120,174,208,225,32,128,13,59,17,133,163,207,206,249,195,195,207,9,219,193,254,175,128,237,96,159,89,42,222,182,206,223,219,199,0,220,163,250,167,208,246,113,240,233,139,110,247,4,9,171,251,168,63,232,117,78,95,241,197,199,75,35,39,219,35,149,38,51,204,135,53,153,228,22,54,103,172,20,175,114,93,206,93,17,166,145,154,231,42,134,43,98,95,124,240,226,118,124,1,59,173,30,4,5,100,0,213,14,188,223,74,152,26,214,185,224,154,130,237,125,195,84,97,189,195,156,202,144,77,96,250,192,29,158,156,82,209,69,45,87,178,160,38,236,186,109,68,153,97,149,40,252,36,216,208,87,189,238,249,153,227,228,233,195,55,237,126,191,245,170,141,76,52,140,122,162,178,73,49,93,189,41,14,33,212,141,93,46,187,88,239,7,179,188,120,55,104,247,137,209,169,224,20,28,208,94,136,105,237,211,243,55,246,179,195,240,136,252,97,238,61,92,250,28,142,126,47,60,251,190,27,249,49,130,127,110,148,169,32,43,8,196,149,246,56,202,55,31,111,15,110,169,64,31,78,228,80,165,183,19,8,248,254,164,245,162,125,178,228,226,202,159,247,218,255,125,222,233,181,143,253,197,231,207,207,218,173,1,124,126,224,92,98,215,115,122,75,239,33,249,200,83,111,247,37,2,158,194,127,107,89,248,22,115,117,193,126,161,70,21,164,194,119,222,147,67,136,114,64,239,117,112,37,128,175,65,157,207,61,125,254,15,223,223,169,54,208,27,196,29,114,179,138,107,58,15,16,178,194,45,3,41,246,162,148,23,24,93,237,209,108,132,135,2,138,164,166,115,65,11,53,253,5,149,177,66,240,249,27,114,167,183,108,134,97,71,238,7,209,131,38,149,191,129,200,133,109,31,185,32,68,183,152,170,252,38,49,170,41,142,190,254,122,27,92,84,76,172,231,206,189,60,47,83,162,93,108,35,24,39,100,240,192,42,90,73,164,34,172,83,135,80,0,167,76,249,159,156,47,83,45,79,38,237,168,204,227,41,185,234,102,161,223,211,92,230,224,27,97,223,227,57,59,171,229,90,83,117,47,167,220,218,90,37,132,248,83,15,50,32,190,12,185,190,91,118,148,252,27,56,166,213,110,112,225,82,255,230,202,232,244,218,59,137,32,95,36,179,76,229,224,251,199,147,175,244,148,199,17,85,37,204,74,231,22,177,85,158,196,124,218,149,234,130,78,86,5,47,201,213,133,13,225,125,9,244,14,67,173,83,37,237,50,27,69,94,42,244,240,30,203,212,168,70,208,10,129,170,207,199,197,39,97,58,118,34,17,155,144,76,216,196,114,78,94,150,217,66,220,200,197,86,56,169,125,15,107,131,29,185,62,8,34,26,66,177,178,208,95,45,241,252,6,29,111,176,17,139,161,221,227,238,38,234,191,183,158,162,146,123,251,209,33,61,201,255,185,98,91,9,228,11,174,85,244,56,32,1,112,107,45,155,202,190,70,35,245,30,189,132,64,46,9,75,163,177,206,111,49,87,15,76,32,182,108,144,239,171,241,254,189,156,98,217,50,97,28,183,3,150,82,232,21,45,147,46,28,13,103,15,132,114,168,49,88,73,153,74,37,5,7,124,170,68,185,92,189,208,74,96,80,37,239,115,105,57,226,169,196,230,82,52,126,50,58,3,76,108,112,58,39,157,5,115,80,217,68,252,234,1,21,122,162,92,198,244,78,219,251,30,133,4,34,41,30,88,230,0,253,147,93,244,5,12,247,192,224,58,134,11,187,151,215,42,47,28,1,65,39,221,88,206,84,122,36,205,202,139,225,96,165,119,187,170,254,81,233,232,35,250,159,32,219,42,199,139,32,127,34,26,60,70,35,18,111,45,133,113,223,184,3,228,22,118,109,20,1,151,203,248,138,221,179,32,227,239,68,230,163,84,25,31,58,230,146,193,114,160,17,12,142,67,95,248,131,55,33,92,216,145,95,14,76,226,137,70,14,196,195,66,19,229,134,236,210,246,27,157,142,24,220,152,4,14,56,49,7,25,76,32,227,43,46,102,86,65,31,151,169,28,177,220,8,170,169,105,183,167,97,22,89,49,85,69,18,55,240,123,246,140,95,130,51,41,140,48,154,35,47,9,215,55,33,32,147,64,115,203,197,142,19,5,193,151,70,216,201,220,52,56,203,86,4,57,102,225,147,0,56,131,222,249,94,155,234,34,102,173,56,137,160,141,80,81,26,196,152,46,68,235,172,179,110,64,247,64,91,25,70,177,67,185,76,83,209,200,149,76,105,213,97,142,232,202,235,139,44,101,115,233,68,89,184,140,45,67,138,64,112,62,115,74,156,208,228,67,180,231,147,233,108,219,137,154,213,177,41,154,16,207,207,157,168,99,168,33,71,158,229,150,235,57,206,49,223,43,77,137,53,7,44,86,222,76,149,115,4,0,50,112,147,235,66,5,248,143,213,26,139,48,176,138,108,111,129,159,106,174,203,108,180,205,105,111,3,219,7,69,197,216,45,114,201,224,227,133,184,33,180,176,212,117,105,125,245,195,7,215,198,106,212,172,47,200,151,171,127,148,73,206,101,6,237,115,95,219,23,246,170,85,20,178,144,114,52,177,4,111,68,180,38,21,94,49,16,203,236,1,223,103,149,166,80,228,186,74,181,17,90,172,213,97,57,45,136,52,102,183,82,58,29,62,103,58,212,234,130,66,228,1,241,103,191,118,23,12,99,173,81,228,235,63,78,229,164,25,130,187,112,1,42,124,196,132,198,60,16,48,112,151,85,110,251,178,66,64,33,141,116,29,81,65,76,88,161,64,32,192,121,245,43,213,117,31,215,190,6,223,65,239,101,186,188,74,241,155,121,102,214,207,190,74,107,122,119,213,175,237,253,157,125,178,234,67,4,5,11,195,193,108,251,149,42,207,117,106,70,230,201,80,118,15,148,129,36,204,175,83,50,170,172,200,147,154,70,17,226,18,87,169,19,235,154,196,176,20,38,187,94,33,230,143,18,83,36,25,87,22,168,45,58,170,42,0,217,43,155,159,52,206,147,104,236,69,133,248,82,14,98,176,68,160,234,125,235,107,189,4,161,224,192,195,144,61,66,207,36,198,86,135,231,248,59,107,62,43,141,63,124,250,145,85,191,168,31,29,165,188,88,32,146,82,155,250,241,133,161,11,107,143,146,110,175,63,207,10,186,222,162,165,117,130,171,27,220,195,179,86,87,155,43,100,210,86,170,98,93,46,143,79,214,199,62,92,69,61,16,18,86,63,102,20,109,27,162,193,202,11,121,103,130,82,19,242,87,92,96,24,127,229,45,94,134,214,85,63,96,0,215,88,41,111,3,175,86,239,102,217,140,10,41,135,151,192,165,217,238,8,108,80,114,97,25,240,213,19,223,74,42,225,222,128,143,67,54,98,119,7,95,155,23,131,8,13,10,226,43,101,218,27,185,192,120,92,200,5,178,172,89,142,156,168,139,69,165,200,151,114,140,129,34,117,99,223,170,48,134,121,89,176,137,172,154,227,134,51,235,3,208,129,205,173,106,58,178,187,178,188,191,94,255,227,235,150,39,99,98,161,41,214,214,135,198,241,231,236,230,180,244,180,226,247,213,250,12,226,7,22,146,159,11,144,170,127,124,182,106,74,170,118,189,52,37,125,190,118,74,252,190,50,229,163,85,83,126,216,0,60,122,254,219,127,192,131,13,119,16,134,132,52,54,206,108,29,84,227,6,63,93,75,94,32,130,147,248,75,211,112,197,41,66,172,242,9,191,130,240,82,79,192,144,9,2,119,96,12,225,244,33,27,6,106,171,165,11,95,64,39,5,247,53,138,112,229,24,193,41,132,0,142,53,197,199,82,85,241,44,153,151,41,48,203,78,94,230,157,102,191,54,182,223,216,193,86,219,111,164,89,178,223,40,241,21,35,91,56,30,173,55,104,205,212,121,161,128,66,147,220,133,78,67,192,87,39,246,198,24,93,227,87,237,243,1,154,59,77,53,143,42,15,209,12,162,193,32,13,25,10,7,26,19,41,96,18,9,89,205,186,205,128,110,4,250,182,88,166,169,26,173,180,110,69,161,82,163,90,59,203,229,120,7,207,172,56,215,6,194,226,87,108,133,120,171,80,139,135,172,173,27,175,208,98,174,241,68,216,155,57,216,43,200,70,118,163,196,176,76,160,250,186,23,254,154,118,203,40,19,7,132,17,185,100,61,6,193,27,42,5,185,229,97,7,209,78,97,52,180,10,198,183,196,13,14,192,87,120,96,195,47,155,115,0,127,170,167,79,46,209,84,141,169,154,27,94,124,5,114,16,55,69,8,65,97,82,41,83,228,140,116,20,139,38,125,9,120,129,21,227,132,208,249,68,102,201,207,228,127,79,165,3,195,178,70,60,75,19,54,149,140,182,4,246,195,221,221,221,93,28,167,152,230,32,79,61,177,63,172,172,36,189,233,66,151,232,213,109,202,156,174,136,253,104,228,28,143,132,171,167,129,103,141,175,47,164,253,98,122,69,80,68,31,93,253,144,124,178,204,148,14,3,182,1,61,172,192,157,197,71,35,83,93,17,118,109,42,128,203,44,18,203,223,168,237,153,21,105,217,15,114,123,146,234,161,76,183,221,137,110,231,106,146,152,34,95,4,142,177,180,9,154,153,152,192,184,239,220,4,250,88,51,144,156,235,237,22,128,123,59,164,62,132,71,19,156,70,113,164,46,100,68,76,174,213,246,17,197,200,110,193,130,42,157,110,212,208,36,133,18,155,86,178,228,106,244,91,228,215,147,171,7,86,174,197,225,56,158,82,189,159,167,64,181,244,13,28,1,198,74,83,21,49,186,226,231,166,4,217,214,126,15,232,4,157,117,70,123,86,95,88,4,222,74,104,133,198,34,58,245,51,163,176,15,59,148,206,130,157,33,208,240,176,135,11,49,47,139,194,101,81,66,188,45,135,219,21,123,53,168,115,241,158,240,229,55,232,187,73,5,21,5,7,57,24,66,100,136,189,230,132,250,159,24,232,98,135,193,79,255,168,61,49,35,75,71,98,4,102,174,7,127,46,12,152,4,26,99,169,134,61,26,231,122,198,168,105,69,240,114,238,48,69,150,133,158,73,78,178,37,13,184,72,147,146,148,113,102,163,226,112,233,125,16,40,103,140,42,80,27,243,173,188,150,206,57,18,19,55,114,240,115,16,131,136,170,210,196,176,66,133,171,225,96,152,36,213,50,16,47,22,172,202,110,6,14,90,60,184,139,163,196,10,158,40,22,234,113,161,50,214,18,5,146,156,211,50,84,198,112,42,137,76,231,51,88,59,74,101,128,37,67,25,95,221,200,124,100,66,65,143,152,197,85,42,219,170,27,243,158,247,142,192,210,8,203,166,149,155,92,206,231,42,199,45,131,77,10,183,136,98,85,162,21,94,105,178,160,230,152,46,142,148,51,46,83,64,165,211,3,59,104,225,89,213,205,45,87,21,132,43,245,41,59,8,198,63,123,31,202,224,209,240,57,62,214,64,212,25,175,44,70,139,82,186,37,4,108,209,226,154,86,148,197,131,240,130,21,231,56,88,232,15,207,232,74,38,180,36,115,217,115,232,25,225,45,4,143,112,138,232,95,119,54,203,94,227,161,202,28,61,185,25,80,135,201,181,104,109,0,200,107,93,57,25,143,18,145,157,98,195,187,21,195,141,183,92,163,223,81,186,62,77,82,175,193,3,77,215,114,229,14,251,209,128,139,44,49,214,221,85,146,1,80,190,202,116,241,213,234,29,226,173,129,5,123,51,33,120,50,173,218,143,48,143,221,82,127,78,69,23,94,211,32,119,143,174,96,223,109,104,23,98,28,107,56,111,71,59,198,183,170,108,176,186,8,242,222,238,42,249,32,80,246,18,109,227,196,62,83,50,254,175,24,155,87,121,161,254,81,202,212,92,200,108,116,49,149,102,106,101,52,152,133,61,67,158,23,121,233,103,65,75,155,47,123,231,81,106,255,227,56,229,88,119,206,63,152,67,198,156,76,168,247,177,66,168,45,147,8,90,113,105,249,232,66,205,230,192,224,204,36,138,14,68,190,49,95,217,249,224,229,246,55,172,208,41,44,225,255,71,9,198,18,16,73,93,66,77,149,178,177,145,60,16,131,80,4,4,112,228,19,164,80,75,159,245,48,112,238,34,174,12,49,69,198,22,100,227,1,169,194,80,201,107,70,39,50,149,182,57,213,52,18,180,88,207,66,82,142,139,66,177,127,241,154,83,195,133,93,196,83,21,95,93,148,197,248,27,123,92,143,87,34,5,194,240,202,231,96,33,170,68,246,128,85,225,26,44,97,153,228,103,229,82,162,117,169,225,27,251,13,106,252,32,240,194,135,28,176,107,145,63,106,10,107,128,193,198,152,175,212,64,210,72,3,209,143,204,11,111,136,213,63,86,118,40,40,133,195,81,247,184,125,209,239,124,223,118,122,66,242,114,17,62,184,165,59,135,68,55,206,29,137,232,9,85,187,194,113,78,58,131,246,69,239,252,116,208,121,211,6,37,67,29,230,145,162,156,209,132,41,39,73,225,179,84,212,143,230,67,69,65,30,238,80,45,70,229,73,120,54,176,111,238,42,57,214,226,149,174,49,22,88,190,235,211,25,139,206,184,154,20,45,28,152,94,156,165,146,195,46,150,245,41,142,37,196,54,24,165,135,210,168,240,81,119,220,9,230,80,158,203,98,218,20,201,216,197,177,70,190,123,96,72,14,123,154,66,22,120,60,203,15,46,13,229,146,97,172,30,169,14,83,101,0,118,212,119,87,118,213,131,89,9,236,130,48,11,190,40,253,32,251,111,18,187,122,236,85,133,69,146,225,227,199,105,90,254,83,136,198,43,236,209,112,93,188,39,17,24,133,56,74,214,18,166,106,162,158,222,217,145,48,11,83,128,208,239,10,161,251,217,194,84,178,192,163,197,181,92,38,117,112,196,166,139,152,243,41,122,40,73,59,123,112,188,170,47,240,134,107,47,131,244,112,149,100,160,158,228,23,60,200,189,225,61,3,157,9,4,178,189,186,34,190,122,188,148,34,60,48,117,44,77,140,59,116,131,166,70,180,223,6,254,136,73,38,198,242,90,131,199,5,222,75,90,8,191,31,65,122,25,162,90,193,78,163,12,183,126,171,115,72,66,214,228,177,44,181,112,254,48,26,105,104,36,68,55,229,132,57,32,255,162,32,107,4,87,179,11,23,19,38,213,14,18,81,163,73,144,50,214,230,229,10,178,30,199,23,52,216,133,27,236,185,216,91,169,8,92,255,144,215,122,175,124,17,150,140,137,139,149,125,191,185,83,223,233,124,85,231,195,253,245,252,73,199,84,226,74,249,160,255,19,191,61,134,189,5,101,48,18,135,66,230,19,5,213,176,139,177,206,103,228,93,97,31,47,53,75,10,219,222,123,174,58,181,35,177,150,150,71,117,137,169,67,62,11,180,47,65,145,214,48,157,226,36,211,185,26,61,227,230,182,63,57,4,41,105,138,208,235,4,60,87,249,17,131,217,120,57,46,229,225,242,57,7,168,253,92,236,31,172,223,167,54,48,236,134,109,252,96,43,192,48,204,74,205,234,213,1,187,164,226,3,45,148,114,158,33,24,102,59,89,98,5,236,128,71,95,127,189,18,41,235,17,160,7,123,33,200,204,19,214,94,50,205,42,21,17,19,127,205,5,94,185,142,219,60,87,62,49,167,21,155,130,46,117,246,187,38,71,185,199,47,194,27,140,78,5,124,111,87,81,251,85,161,174,7,206,83,240,212,69,206,218,125,88,154,246,89,165,224,127,240,144,173,154,105,69,48,238,129,243,78,243,226,190,232,223,36,227,98,41,171,32,120,154,47,43,2,44,243,113,196,222,84,206,200,139,201,13,237,164,15,162,7,200,60,66,109,59,19,115,90,69,212,51,97,153,122,90,55,123,60,154,29,179,152,13,117,234,178,214,131,40,66,94,83,133,231,87,77,88,248,191,137,46,12,156,0,17,219,145,211,26,85,204,96,127,142,117,211,185,153,86,197,146,217,61,9,14,232,201,18,131,52,159,206,239,138,78,182,233,210,81,18,89,88,66,163,99,58,21,46,224,188,50,101,254,116,94,71,161,195,93,134,240,156,119,131,184,124,43,48,98,182,24,151,142,3,176,65,143,87,3,230,64,112,246,123,132,99,233,60,130,26,211,69,189,208,127,232,197,231,203,230,143,84,161,242,153,143,110,118,192,172,91,100,136,187,135,123,191,121,133,46,83,23,47,149,233,124,109,203,111,93,170,215,154,132,171,117,174,144,35,34,192,159,184,90,6,175,186,236,195,187,45,155,183,95,143,69,94,14,23,191,241,92,201,117,232,87,159,44,128,240,17,218,100,191,15,184,222,195,135,142,110,255,154,8,43,190,154,106,69,170,27,126,160,26,93,182,23,178,230,248,51,132,100,161,206,241,55,70,100,253,70,232,215,133,112,193,194,200,245,226,224,155,74,136,91,45,242,241,23,71,218,224,13,13,204,2,222,15,116,143,59,217,86,97,172,204,184,226,219,94,203,158,238,18,10,217,86,78,199,187,109,89,28,89,80,117,120,175,107,168,205,224,24,39,172,80,241,78,151,28,204,227,205,71,9,85,5,113,201,56,48,54,236,169,16,157,226,129,17,169,203,241,175,198,227,36,78,192,175,127,106,217,22,117,163,114,151,20,190,201,21,169,102,246,185,2,6,12,28,226,70,213,132,254,222,209,144,125,60,89,109,166,222,75,72,28,18,154,235,72,96,116,138,124,173,121,163,189,207,145,11,132,55,170,184,176,107,190,160,93,229,236,22,174,125,112,202,135,238,136,233,219,15,203,126,91,42,176,189,66,70,116,204,122,156,45,28,200,232,38,248,44,216,116,19,248,237,64,243,250,177,226,87,173,170,149,83,143,81,176,1,71,9,222,23,43,27,129,140,195,12,225,51,76,217,0,111,54,217,155,217,63,8,60,111,12,106,106,13,48,195,117,191,213,202,244,47,156,7,35,177,190,108,60,65,90,69,169,138,111,192,34,87,228,73,92,56,91,44,68,17,100,99,157,199,129,184,88,172,74,210,177,204,124,174,63,167,189,245,92,243,49,42,228,43,217,215,131,192,9,83,200,108,36,243,145,104,140,2,213,109,3,52,121,198,232,156,61,174,98,73,70,150,88,103,227,52,137,11,14,173,65,245,31,143,198,214,242,32,15,236,76,73,136,220,199,124,200,46,1,68,192,122,208,221,86,210,36,42,127,38,50,117,67,114,43,165,48,191,214,9,163,10,87,251,242,192,54,150,247,41,211,23,188,172,11,223,240,130,151,100,197,140,219,165,49,70,221,223,93,32,11,238,201,39,74,97,36,128,49,14,221,77,10,11,209,249,35,130,216,58,57,204,81,243,195,166,120,216,244,209,69,111,3,7,108,222,58,188,24,85,83,99,192,7,201,57,184,138,46,240,214,210,86,176,82,103,110,66,37,117,224,161,238,190,241,212,77,216,79,255,242,55,181,24,44,230,170,41,192,71,206,254,250,87,251,249,5,103,67,216,123,86,123,219,71,161,167,125,170,245,149,113,233,221,121,88,126,170,228,28,252,191,218,0,110,64,64,67,34,42,231,23,184,156,37,178,89,113,239,36,48,197,149,90,4,64,45,53,115,139,8,221,121,93,211,15,254,87,239,157,87,1,114,197,202,9,191,107,161,169,224,79,52,213,218,32,109,10,211,89,195,89,242,178,192,218,225,17,21,19,110,35,167,41,164,200,48,204,215,158,105,82,185,21,78,3,87,104,49,181,15,185,253,238,74,45,48,200,144,252,84,253,193,4,70,136,214,89,7,152,22,112,215,93,10,168,45,194,76,205,144,32,137,173,155,201,216,199,228,224,133,88,29,130,80,241,54,238,14,218,79,57,25,13,169,166,28,35,90,75,229,37,90,104,126,101,238,4,48,18,211,126,176,25,26,68,63,12,97,162,65,136,148,177,135,12,212,196,247,138,48,212,103,18,71,207,244,159,52,216,192,133,174,120,11,2,116,123,92,189,153,20,239,250,147,188,150,105,82,216,231,130,76,11,67,8,99,113,237,158,248,118,153,204,244,133,52,23,182,253,111,225,129,63,87,150,129,207,194,210,222,57,201,64,37,123,192,138,92,11,49,16,40,135,14,108,132,40,86,167,212,39,198,85,122,223,61,167,158,88,17,184,72,62,98,83,153,217,109,117,94,9,55,22,93,34,225,24,114,86,225,146,226,138,96,196,130,121,162,98,79,35,185,105,161,10,127,105,130,132,222,115,197,41,82,25,42,40,101,8,117,147,116,158,47,154,226,70,61,72,83,1,116,89,115,169,62,136,84,1,47,187,18,202,122,144,102,251,63,66,180,60,2,106,21,147,175,106,133,35,193,112,124,208,150,130,229,236,168,154,137,129,69,223,25,37,33,18,194,197,239,239,82,106,238,163,110,239,56,168,133,130,223,95,156,117,218,71,109,38,141,31,66,180,133,152,48,218,17,46,208,138,246,126,12,244,97,204,156,231,201,44,1,210,69,252,5,184,138,209,77,217,217,17,18,185,113,199,184,47,157,34,110,171,229,198,34,209,171,20,148,195,25,152,151,229,186,47,72,26,39,46,196,218,251,13,40,60,171,102,24,118,32,243,92,46,64,74,166,210,101,76,228,156,91,93,90,15,226,31,166,122,24,137,14,71,227,53,145,230,176,230,221,146,155,2,179,1,186,128,59,120,221,201,179,4,88,45,178,42,224,38,134,161,242,53,85,55,54,8,34,121,237,222,255,100,194,219,194,34,185,242,190,66,125,120,114,113,241,78,77,65,174,158,58,136,230,164,64,190,144,138,90,97,206,37,232,117,5,40,31,29,138,33,224,103,161,38,57,20,115,177,220,226,123,142,192,198,209,54,161,14,86,147,234,97,53,237,246,193,191,208,16,62,160,223,182,160,104,175,79,52,194,11,250,182,79,89,37,156,230,194,161,2,156,75,184,54,212,47,48,235,12,155,106,68,170,49,128,210,50,89,9,88,206,189,209,31,75,194,204,237,229,188,193,48,77,44,174,228,2,96,41,162,148,212,121,98,156,106,228,230,208,51,212,79,205,114,60,86,178,176,45,190,237,95,156,158,191,121,209,238,57,102,147,22,4,18,76,189,40,83,176,8,114,76,246,175,124,237,0,27,232,39,214,224,16,124,176,141,170,169,188,78,116,30,184,78,195,205,198,243,195,161,44,64,221,222,155,214,9,68,229,84,222,117,151,72,174,88,42,98,231,49,192,197,82,105,66,134,208,166,135,158,50,232,17,7,165,43,176,224,43,41,208,181,158,68,51,89,76,163,142,197,149,218,179,250,109,31,168,18,237,78,205,227,220,1,237,137,24,181,119,84,236,220,168,106,248,248,130,171,119,248,21,123,130,70,29,150,144,198,184,46,142,6,238,173,237,226,60,245,120,22,60,104,71,16,43,6,220,192,37,121,232,56,224,84,254,156,164,139,255,20,226,68,254,188,96,235,136,51,140,208,195,184,109,151,18,92,74,131,46,182,86,176,227,50,179,236,239,130,110,89,129,0,64,165,45,210,5,205,216,244,23,60,129,140,1,212,246,129,241,161,246,88,133,3,195,123,8,206,33,84,228,65,239,111,224,70,208,228,140,84,209,235,104,8,13,43,35,19,101,139,11,244,44,245,99,2,208,148,20,2,114,55,160,128,88,87,184,144,155,161,221,18,9,30,247,118,245,53,118,212,74,246,227,92,41,84,135,2,51,237,34,82,53,213,70,2,179,240,68,229,2,10,162,252,188,112,238,240,213,248,106,231,248,238,248,25,246,81,119,254,55,56,24,83,242,138,54,214,242,232,166,156,76,148,41,130,178,96,78,183,32,33,183,174,229,27,18,117,77,165,124,248,130,67,229,159,16,174,74,176,60,228,65,210,57,41,201,130,27,55,212,250,234,74,41,159,45,67,95,171,124,10,149,209,22,115,18,250,40,173,95,197,19,37,89,123,199,93,241,53,137,62,65,69,144,237,210,213,117,167,234,62,213,74,74,36,33,201,52,101,223,51,8,38,199,122,135,185,154,201,32,186,39,18,226,101,153,219,35,178,47,188,69,203,92,201,209,182,145,99,229,50,22,50,158,6,197,228,61,92,65,30,79,4,252,25,24,236,11,246,174,225,9,237,136,142,142,198,80,214,53,215,51,239,168,140,19,3,250,187,74,245,240,116,164,24,64,93,29,212,94,146,36,227,60,5,224,243,13,145,195,66,113,110,52,66,227,96,119,235,154,185,186,48,181,44,2,130,27,149,11,74,102,222,8,93,250,153,1,1,92,169,56,73,163,163,106,98,154,176,76,139,66,29,211,193,251,159,252,172,70,155,91,204,46,85,168,4,75,252,11,145,171,162,204,9,137,185,216,105,177,116,157,167,210,8,200,163,14,87,167,2,97,77,241,155,41,187,17,50,95,56,95,96,205,110,51,43,198,5,150,155,2,63,180,247,32,66,90,17,86,0,154,171,28,82,231,67,214,12,187,81,77,75,243,149,116,252,221,188,204,231,26,13,212,118,147,252,64,150,141,18,162,149,213,159,61,82,177,193,17,152,143,158,1,109,22,105,56,93,44,122,65,169,61,147,34,60,5,86,74,7,238,30,193,121,133,148,184,10,14,12,79,153,245,191,66,103,227,175,8,156,4,202,55,84,64,2,165,213,87,224,159,248,21,33,249,250,166,85,90,199,52,18,99,243,43,186,163,41,115,186,67,165,50,58,133,101,22,20,112,112,77,60,90,221,185,194,18,177,223,93,153,199,58,70,243,235,84,121,213,218,209,183,59,84,48,210,255,10,69,222,175,74,208,91,157,7,50,2,175,245,189,253,183,210,34,84,52,163,207,72,178,158,105,251,231,79,192,61,5,106,134,74,218,128,127,130,148,142,255,119,148,45,97,58,130,32,166,164,110,92,102,91,32,86,128,159,97,222,115,175,90,193,172,167,144,102,59,40,232,136,163,185,156,80,85,172,133,145,46,100,154,200,74,13,100,38,20,20,234,254,5,148,254,24,21,240,251,147,9,176,105,253,86,117,255,195,117,202,194,127,99,244,173,4,227,255,178,2,141,144,143,255,98,200,132,243,125,9,35,82,144,39,226,22,196,250,136,101,242,223,15,105,106,41,17,152,236,89,206,252,169,64,245,179,11,111,221,115,81,173,7,251,156,162,192,103,162,116,213,184,220,195,221,59,59,98,163,208,56,151,51,117,163,243,171,72,136,183,74,200,185,78,245,132,139,88,79,181,204,71,196,169,154,32,167,171,22,186,204,141,74,175,149,9,172,59,66,220,40,42,124,75,121,122,80,80,4,215,93,200,224,197,117,173,45,158,199,9,137,121,172,85,230,98,44,60,24,213,100,137,106,52,215,71,69,125,129,155,66,147,125,137,107,194,14,192,183,17,223,143,240,104,255,126,151,164,154,214,226,254,142,56,127,4,80,104,124,33,119,4,59,215,151,241,70,112,145,72,191,242,130,212,246,199,36,35,181,141,193,100,219,160,145,219,212,57,170,96,146,76,188,30,12,206,236,109,74,101,22,171,45,92,223,72,205,230,218,138,208,4,185,149,69,81,246,253,79,108,15,117,121,32,78,162,46,38,123,181,201,171,246,192,238,193,16,67,198,228,216,165,11,132,213,161,103,215,217,121,208,198,79,235,52,59,172,222,172,169,206,207,186,253,129,11,57,235,112,183,120,113,2,209,147,168,125,238,28,183,223,156,117,7,237,211,163,119,23,231,167,127,59,237,190,61,69,85,179,253,242,180,123,209,239,28,183,47,218,47,95,182,143,6,125,159,128,10,140,208,202,4,176,84,7,27,248,192,50,108,239,183,10,211,221,112,22,20,136,64,197,61,55,245,16,176,37,136,19,255,193,5,70,128,62,23,7,135,20,240,22,156,242,138,53,253,27,18,69,172,27,54,115,33,154,100,113,178,87,71,58,41,201,239,134,83,157,186,197,83,220,3,56,213,237,236,184,10,235,73,230,32,165,148,34,152,234,143,99,171,156,23,194,211,167,103,148,160,5,67,173,93,218,38,200,130,100,111,42,165,78,50,68,44,65,171,14,217,76,44,144,199,65,46,75,136,103,48,81,24,101,20,216,178,9,140,36,171,228,191,196,62,84,209,12,245,131,8,163,31,248,233,83,26,98,115,171,73,57,114,168,154,229,82,195,35,61,95,12,244,230,214,22,23,250,190,134,132,177,215,106,21,26,24,95,184,50,72,242,181,10,95,2,25,62,12,194,171,160,145,215,226,67,106,33,151,117,140,14,20,243,117,77,40,8,144,85,172,35,93,108,115,192,249,136,253,234,18,115,225,131,111,41,197,170,72,198,227,96,132,112,88,26,204,119,217,28,169,76,23,28,94,139,121,166,237,201,85,144,194,204,85,108,234,174,47,28,41,215,142,38,81,243,23,241,3,213,190,66,122,220,20,63,52,134,50,143,134,242,231,70,19,195,96,236,71,255,40,223,187,38,226,67,0,25,14,5,117,179,54,169,223,86,100,91,135,153,245,78,229,76,157,201,188,32,58,231,212,137,65,182,175,139,57,103,213,171,54,129,87,164,178,87,129,159,128,187,254,110,2,74,16,80,49,101,7,102,152,213,167,217,196,210,232,178,0,68,2,187,33,188,192,250,74,217,187,71,46,60,9,231,196,130,196,69,210,112,41,55,167,17,110,147,227,174,118,181,245,141,10,74,216,27,181,50,134,199,13,155,187,180,207,213,172,240,104,234,22,115,109,192,195,225,34,201,124,130,232,195,122,222,185,71,135,174,88,67,165,225,195,74,195,145,46,135,169,162,127,92,155,71,213,48,56,200,109,77,241,216,65,66,234,229,21,184,122,3,174,217,55,156,26,238,179,166,244,170,150,185,130,154,83,152,228,43,139,229,220,80,174,172,187,213,201,194,84,15,185,158,177,109,127,3,114,195,45,215,163,187,145,65,148,114,144,130,175,90,174,138,40,71,75,156,112,157,254,196,39,80,147,98,158,40,52,117,85,193,23,178,154,51,195,66,66,154,119,157,231,202,204,117,134,158,44,50,84,253,251,52,102,206,57,183,90,124,11,243,241,4,57,104,125,114,220,66,219,247,24,114,155,143,40,133,184,202,77,179,22,39,224,163,183,40,217,69,50,75,82,153,243,120,84,186,43,244,230,164,20,57,77,97,228,194,178,199,232,32,142,203,170,248,98,126,212,129,221,99,212,88,235,138,83,37,249,4,157,40,240,195,215,250,74,200,2,83,178,121,223,43,191,47,110,182,219,134,253,31,98,138,254,231,127,220,63,246,127,255,243,63,220,64,82,131,97,12,255,140,148,16,99,33,38,211,4,27,188,85,62,193,152,47,153,156,18,14,120,199,86,51,151,153,16,16,82,94,75,4,80,167,163,66,252,32,155,201,150,16,63,136,195,166,216,109,138,253,166,216,21,63,66,91,75,202,110,166,58,93,94,112,20,116,30,214,58,55,197,161,237,111,59,99,97,137,77,222,149,45,223,45,110,142,150,186,61,228,110,88,27,1,183,48,232,163,154,227,165,62,123,220,7,83,81,141,181,14,58,76,154,211,165,14,7,174,3,102,112,218,220,219,170,103,143,229,109,220,22,45,183,181,100,102,116,25,26,221,59,64,54,238,194,168,116,76,245,28,200,12,231,82,150,136,240,50,97,30,123,202,113,150,20,91,129,191,123,201,190,5,152,177,3,28,60,245,152,221,187,176,98,56,13,104,69,78,180,144,171,44,78,53,25,26,157,111,23,58,193,227,155,30,137,234,133,1,47,152,34,241,99,97,101,5,49,76,117,124,37,54,231,218,152,100,152,46,194,180,254,206,226,236,159,196,32,181,33,242,68,60,26,69,106,144,165,214,109,223,205,212,74,59,128,143,176,139,78,235,222,240,60,108,195,237,170,147,181,43,245,2,101,134,187,23,241,241,188,97,184,220,5,240,162,133,11,42,176,115,242,38,163,167,148,97,87,41,220,173,218,158,134,217,106,161,130,192,60,7,225,202,2,128,89,252,220,118,64,146,8,74,7,42,102,218,56,177,94,15,175,19,93,26,222,116,46,150,129,107,29,53,104,175,229,68,38,153,203,123,198,169,243,92,174,183,21,199,83,205,173,107,98,61,87,77,244,1,4,155,168,203,40,183,98,7,150,81,250,129,65,50,193,190,9,232,156,12,233,203,8,243,146,194,16,155,71,109,17,151,60,100,132,82,193,218,148,106,160,135,69,5,87,252,134,178,24,129,254,37,60,210,80,77,146,12,80,141,120,166,250,78,97,124,147,153,202,28,121,243,90,174,194,208,191,0,115,169,65,63,183,232,111,209,236,141,166,124,185,106,7,194,101,27,61,227,188,83,181,150,60,131,147,150,102,74,186,132,209,56,140,149,65,84,54,146,43,46,158,104,64,33,166,6,9,126,142,0,67,249,28,137,84,207,174,52,72,73,233,110,116,37,133,178,79,241,228,49,159,7,243,15,121,130,85,18,56,112,152,188,27,237,192,148,130,37,201,65,88,211,153,247,157,170,228,211,22,219,226,200,167,106,192,212,220,224,217,75,220,108,112,237,136,231,156,231,122,40,135,232,43,133,213,179,65,99,197,176,161,242,71,20,64,11,120,215,88,234,198,136,235,66,102,163,166,101,117,193,123,22,157,242,244,56,152,41,246,73,33,4,230,103,142,117,62,10,114,63,129,159,113,69,82,119,44,146,163,70,244,36,51,111,224,26,56,151,188,32,27,45,37,210,180,172,62,33,231,58,174,141,99,211,40,245,56,143,197,179,114,193,48,254,188,29,248,238,146,198,43,208,81,82,126,125,36,120,148,203,4,156,71,36,82,81,203,74,186,42,95,84,225,103,37,100,28,105,111,105,21,37,195,41,42,185,105,221,165,38,113,207,93,234,196,192,84,79,249,43,122,74,15,224,41,125,12,111,47,127,229,104,122,208,24,146,39,132,165,114,55,15,182,224,43,59,134,111,102,127,34,88,249,230,227,173,48,95,145,157,164,214,204,62,242,155,91,213,180,70,123,174,78,27,61,163,124,207,87,108,70,5,28,140,164,12,183,252,48,128,254,147,138,255,162,212,157,45,53,198,117,45,79,180,191,106,162,219,43,178,186,105,86,230,148,6,14,104,105,170,189,96,170,143,229,234,14,49,211,147,23,140,71,4,132,243,133,128,220,53,210,190,52,4,169,24,58,99,203,140,147,3,67,136,158,169,52,5,35,251,26,132,242,216,228,80,175,198,43,84,121,81,255,168,108,186,212,75,238,33,225,161,232,202,34,35,202,212,16,28,203,217,208,50,75,98,157,234,108,43,218,168,4,69,81,153,107,11,4,216,34,157,207,186,207,221,134,18,24,62,155,83,72,123,140,210,120,49,205,149,194,164,180,101,238,216,183,167,148,48,50,77,50,43,182,192,239,177,78,203,25,37,237,130,250,7,35,248,218,115,204,205,192,241,76,26,83,206,212,8,223,116,105,130,225,182,154,208,21,71,139,252,41,114,142,114,130,61,201,48,147,27,190,40,184,141,16,68,64,49,10,241,34,18,129,179,159,29,57,68,58,28,222,217,52,236,192,63,171,92,99,249,121,96,99,156,219,230,66,151,248,158,220,80,4,167,28,57,108,216,131,72,9,75,251,200,184,49,74,204,60,149,139,132,139,250,148,20,182,180,116,24,240,86,67,8,230,186,195,224,20,167,53,97,185,162,44,115,169,212,2,12,226,116,137,18,210,125,44,120,184,88,207,136,243,6,174,37,241,6,25,120,166,161,50,14,210,82,143,139,36,221,67,7,231,14,136,123,72,137,190,25,13,195,39,189,118,1,91,144,213,141,158,62,208,17,47,67,162,51,240,226,83,113,9,81,40,182,153,193,148,93,34,211,136,54,238,62,233,43,203,245,86,250,226,35,236,122,161,161,166,32,85,46,148,58,114,178,4,76,93,7,49,85,210,114,24,23,35,133,171,186,112,32,194,96,87,74,205,237,163,41,39,185,156,79,97,33,174,1,96,23,2,195,163,209,182,110,14,203,2,248,170,88,103,25,122,202,22,122,11,213,202,232,225,202,215,41,194,231,211,205,224,238,144,215,122,14,23,152,34,162,190,72,237,247,211,63,191,200,60,4,242,7,154,181,56,220,47,92,121,23,124,220,167,126,16,114,63,15,51,6,60,115,95,206,100,126,101,175,11,42,162,119,118,182,72,140,67,96,161,98,144,2,233,130,216,69,100,120,121,175,154,188,207,22,175,10,202,170,1,200,151,9,105,10,149,39,230,138,7,115,9,123,121,208,101,170,8,226,36,164,55,179,72,165,125,208,17,42,53,114,227,142,89,156,170,27,216,55,184,19,20,204,229,131,193,160,186,192,18,67,227,210,22,87,63,95,170,83,193,90,17,180,136,208,70,133,215,99,172,117,228,123,175,105,52,148,121,180,118,138,161,204,195,87,115,253,27,56,148,63,251,234,182,31,159,238,231,42,76,173,140,100,4,187,151,107,90,222,58,234,63,202,247,149,81,239,54,67,181,87,93,201,250,143,242,125,200,152,84,134,60,166,235,234,240,19,107,0,228,147,160,82,148,189,128,140,118,58,23,69,46,19,240,201,102,164,172,12,136,208,8,30,37,44,209,148,35,65,29,166,50,187,194,75,200,183,147,226,200,66,30,22,201,128,70,73,245,19,192,246,36,128,107,204,126,236,180,177,139,171,24,140,195,127,37,94,132,151,206,237,116,192,124,126,133,137,107,97,155,196,9,237,13,95,64,83,105,200,215,144,152,160,72,124,181,115,135,185,80,74,242,163,76,114,200,192,85,233,92,67,113,108,226,11,29,215,182,140,44,237,98,84,219,58,83,171,26,68,59,195,244,220,81,105,119,41,234,45,25,31,194,166,135,207,170,15,118,109,208,229,71,130,160,254,176,84,208,5,201,112,138,210,222,52,153,139,161,42,110,148,202,106,1,27,168,18,40,76,93,207,190,225,242,32,183,124,162,86,199,8,132,249,5,140,209,113,34,157,57,203,37,122,119,243,64,73,9,175,188,247,166,107,78,96,12,204,41,100,167,181,216,225,61,75,169,83,37,246,219,233,241,151,129,98,85,126,38,90,206,173,130,31,64,131,202,8,224,124,44,43,171,222,195,91,85,219,11,80,54,242,91,182,193,124,111,226,211,157,218,179,168,229,226,118,71,21,76,234,221,58,234,18,114,208,104,149,140,12,126,132,213,167,180,110,255,168,148,195,243,69,51,92,221,107,67,169,114,224,205,103,205,149,172,179,114,17,139,234,17,43,181,126,5,203,94,3,28,14,8,18,89,98,95,98,207,86,47,96,245,229,193,38,144,83,218,153,2,87,77,5,44,59,190,195,99,163,96,175,208,232,69,155,86,61,87,47,14,201,2,239,132,119,86,14,76,131,104,234,94,89,11,12,30,126,87,255,103,229,169,145,7,208,93,224,225,160,47,146,248,215,194,3,99,97,18,3,149,241,223,129,89,210,222,178,185,52,197,146,124,152,171,84,93,67,89,194,69,161,196,38,213,121,193,64,101,87,100,216,94,129,231,48,240,54,174,111,235,35,101,208,14,153,200,252,225,254,231,247,255,65,79,140,29,204,88,187,195,25,107,119,70,37,73,57,240,201,111,156,99,119,119,119,247,209,225,33,252,187,187,187,91,251,119,111,239,240,224,241,31,246,14,31,238,30,236,31,62,62,216,123,252,135,221,253,221,195,195,195,63,136,221,207,180,198,143,254,148,246,130,255,97,119,55,215,186,248,88,187,219,190,175,47,238,255,145,31,46,231,25,235,148,157,17,197,182,247,166,132,220,133,160,61,166,196,127,72,241,161,172,148,158,47,242,100,50,45,196,254,238,238,55,212,69,116,178,152,202,94,195,119,190,166,62,120,19,125,98,89,20,170,98,212,83,163,196,82,237,97,73,79,30,38,247,76,56,185,5,124,50,76,50,153,163,190,149,101,106,200,190,15,118,40,40,13,165,71,201,152,138,18,53,81,199,226,210,11,184,172,113,46,138,214,91,106,99,157,141,184,32,24,150,249,154,169,226,41,129,134,156,95,21,64,83,55,226,83,169,56,87,65,1,53,116,49,239,159,29,39,211,5,184,41,131,42,36,77,76,129,210,183,159,153,50,176,123,176,70,137,137,83,153,204,84,30,173,7,196,62,14,126,95,24,16,242,152,242,176,108,128,226,132,143,243,183,192,226,221,168,106,238,2,50,27,237,232,156,228,215,153,44,32,77,77,144,174,143,83,242,217,1,194,53,4,139,59,165,40,197,34,112,189,10,177,46,211,254,59,67,220,20,174,44,195,225,116,238,138,93,113,109,127,149,141,116,110,20,249,145,205,116,161,200,159,172,48,149,36,241,27,172,226,52,122,92,220,88,228,97,11,167,203,183,61,207,19,139,112,185,197,168,12,113,203,24,90,1,84,78,123,221,233,139,126,247,229,224,109,171,215,22,157,190,56,235,117,191,235,28,183,143,197,139,119,98,240,186,45,142,186,103,239,122,157,87,175,7,226,117,247,228,184,221,235,139,214,233,177,56,234,158,14,122,157,23,231,131,110,175,111,135,105,180,250,162,211,111,192,119,173,211,119,162,253,247,179,94,187,223,23,221,158,232,188,57,59,233,180,143,197,219,86,175,215,58,29,116,218,253,166,232,156,30,157,156,31,119,78,95,53,197,139,243,129,56,237,14,236,32,39,157,55,157,65,251,88,12,186,77,152,122,185,167,232,190,20,111,218,189,163,215,173,211,65,235,69,231,164,51,120,7,83,190,236,12,78,237,116,47,187,61,116,87,60,107,245,6,157,163,243,147,86,79,156,157,247,206,186,253,182,176,235,59,238,244,143,78,90,157,55,237,227,72,116,78,197,105,87,180,191,107,159,14,68,255,117,235,228,164,186,92,240,221,121,123,218,238,217,53,132,203,21,47,218,226,164,211,122,113,210,182,211,193,106,143,59,189,246,209,192,46,203,255,118,212,57,110,159,14,90,39,224,16,216,63,107,31,117,90,39,77,209,254,123,251,205,217,73,171,247,174,73,195,246,219,255,125,222,62,29,116,90,39,226,184,245,166,245,170,221,23,155,183,239,206,89,175,123,116,222,107,191,177,176,119,95,138,254,249,139,254,160,51,56,31,180,197,171,110,247,24,182,189,223,238,125,215,57,106,247,159,137,147,110,31,54,238,188,223,6,96,142,91,131,22,76,127,214,235,190,236,12,250,207,236,239,47,206,251,29,216,194,206,233,160,221,235,157,67,157,227,45,241,186,251,182,253,93,187,39,142,90,231,253,246,49,236,117,247,212,174,25,113,167,221,237,189,179,67,219,253,128,211,104,138,183,175,219,131,215,237,158,221,94,216,181,150,221,142,254,160,215,57,26,132,205,186,61,49,232,246,96,97,126,189,226,180,253,234,164,243,170,125,122,212,182,13,186,118,160,183,157,126,123,75,180,122,157,190,109,208,129,201,197,219,214,59,209,61,135,181,219,67,59,239,183,225,184,94,86,209,185,9,167,43,58,47,69,235,248,187,142,133,159,218,159,117,251,253,14,161,15,108,223,209,107,218,253,104,99,3,243,104,137,231,162,129,233,107,26,207,54,54,56,67,107,45,133,254,179,141,13,78,240,179,156,99,186,129,84,32,58,227,124,251,111,85,154,254,45,211,55,217,96,49,87,166,241,204,245,93,78,232,141,217,219,232,251,74,93,132,6,129,48,209,169,204,38,145,206,39,158,61,194,172,206,80,106,207,177,74,243,161,159,168,86,45,170,17,235,89,84,91,81,173,241,114,249,162,198,49,13,12,203,170,53,95,170,137,83,89,199,170,140,223,141,87,103,47,236,6,195,165,229,161,107,62,169,96,252,165,52,57,219,196,195,59,57,54,153,169,48,11,14,56,24,163,114,190,204,208,6,175,98,240,69,3,163,117,46,99,255,22,242,23,133,200,100,166,241,207,13,16,72,140,78,145,204,83,25,191,176,78,30,101,125,136,101,170,178,145,204,201,160,145,97,209,153,52,185,82,162,49,146,139,6,185,1,55,102,58,43,166,13,30,8,101,29,160,241,131,100,166,76,33,103,115,87,41,26,158,39,146,253,99,197,234,10,160,241,55,97,123,174,73,105,151,233,182,12,181,24,156,104,10,242,206,216,249,77,57,44,236,162,113,103,64,143,43,253,80,17,213,111,198,172,244,185,126,159,204,176,0,245,215,219,123,187,205,221,221,93,177,80,50,119,37,59,255,232,20,179,174,144,35,122,165,236,61,21,71,122,54,47,11,229,1,66,157,113,8,56,60,252,115,163,202,145,6,14,36,10,184,21,191,58,46,81,29,69,209,179,229,111,81,24,11,191,115,19,50,198,251,239,185,137,19,27,248,200,65,234,115,127,109,227,156,252,247,179,165,110,128,30,212,9,127,231,46,240,87,56,85,50,22,155,75,211,253,69,236,138,63,255,185,62,222,95,197,238,150,248,101,195,217,164,151,186,125,13,170,147,229,239,9,132,231,224,169,143,63,174,217,7,161,82,203,132,174,2,227,175,43,193,248,203,109,96,108,127,20,140,175,87,131,81,67,144,125,143,32,254,44,1,67,252,159,95,251,163,252,181,120,242,17,92,248,24,30,241,215,33,82,60,175,34,133,248,122,105,99,158,133,221,24,69,2,180,8,187,172,196,19,223,175,126,6,21,236,172,110,191,239,180,102,231,61,2,248,166,127,13,155,174,157,233,235,117,51,173,65,181,218,25,31,172,35,2,35,89,40,168,205,100,255,51,82,41,200,110,226,108,81,76,61,27,106,127,10,123,36,203,141,55,71,114,97,158,31,52,197,44,201,202,66,153,231,123,187,91,245,43,42,158,187,57,55,151,190,140,94,230,122,54,112,195,21,163,45,71,207,190,237,119,79,197,27,140,232,167,15,59,25,126,138,34,37,58,47,184,245,128,171,70,37,23,158,47,104,150,7,169,247,36,144,109,212,167,53,3,95,25,106,10,149,106,216,1,175,28,219,167,176,97,26,98,51,201,70,137,139,219,132,67,129,170,167,27,168,214,156,231,42,134,36,70,20,31,195,238,61,238,41,99,163,173,123,205,140,80,239,237,211,104,48,109,31,188,0,248,2,202,148,59,69,85,223,178,3,247,46,194,88,187,149,209,156,230,13,42,8,211,30,36,149,13,179,91,210,56,48,13,78,31,116,80,121,128,247,130,225,184,44,15,102,191,246,128,174,26,47,98,236,219,179,35,219,145,106,227,130,0,156,196,121,117,236,187,14,188,103,26,132,136,78,187,238,142,156,147,194,163,11,26,79,202,201,166,3,54,36,18,111,40,39,14,96,253,246,193,222,195,230,195,199,143,236,51,106,255,239,92,218,191,174,125,129,54,81,147,92,171,136,66,76,209,133,96,168,75,88,30,101,98,47,185,212,24,249,20,63,218,181,192,236,204,146,76,124,101,255,152,37,217,206,52,23,95,137,253,67,49,205,119,70,114,33,190,18,7,143,30,70,251,15,133,189,65,59,246,41,23,95,225,77,198,119,125,67,80,216,133,39,122,174,182,4,173,183,194,49,73,106,88,101,153,2,126,41,220,22,103,61,192,189,225,253,196,92,244,120,75,116,166,220,136,121,133,141,227,204,222,180,107,151,4,224,101,224,118,40,93,84,9,198,75,98,224,136,184,4,192,46,57,117,163,197,109,166,3,198,129,20,76,172,115,129,201,183,176,116,225,207,42,215,20,116,195,145,168,149,17,57,239,209,70,232,19,132,62,180,80,255,16,117,225,53,120,235,152,241,228,201,147,38,253,223,99,69,240,97,128,17,120,68,7,251,130,31,152,253,103,255,14,58,232,53,250,95,44,212,241,57,148,191,183,234,127,119,15,31,62,126,88,213,255,238,61,126,252,104,255,94,255,251,37,126,238,245,191,247,250,223,123,253,239,189,254,247,94,255,123,175,255,253,151,215,255,254,42,253,46,176,66,159,93,185,219,182,163,126,86,205,238,109,58,110,188,174,92,178,21,221,108,89,6,131,103,111,161,75,208,106,230,106,27,188,1,53,101,136,199,176,19,75,230,75,174,82,5,82,105,56,2,60,53,80,149,169,117,214,49,145,104,177,103,121,37,158,14,139,37,96,92,60,58,141,253,163,84,166,32,13,46,126,98,230,58,163,42,248,20,149,214,58,235,80,222,20,148,50,146,204,20,50,139,85,248,6,115,82,41,12,25,118,154,149,124,30,139,23,50,223,172,23,228,133,221,223,162,28,19,70,172,249,126,73,1,51,152,42,20,108,107,133,1,172,0,115,9,125,46,93,149,59,108,136,138,9,113,249,203,135,75,239,79,6,45,197,47,255,20,210,197,26,254,31,164,169,139,153,52,87,159,65,8,184,197,255,227,241,227,199,123,117,255,143,199,251,247,254,31,95,228,231,158,255,191,231,255,239,249,255,123,254,255,158,255,191,231,255,255,229,249,255,207,194,185,67,32,239,27,105,174,126,15,238,253,87,73,40,192,172,89,94,45,148,82,62,42,7,92,186,69,92,214,211,146,161,43,7,212,43,79,98,82,197,207,101,49,165,18,3,196,206,135,239,31,124,251,84,52,198,145,108,44,127,54,140,70,13,106,252,90,229,74,92,142,107,83,186,196,9,16,54,1,49,241,174,104,193,165,188,132,231,230,114,120,185,225,10,210,240,3,227,10,252,233,50,131,1,46,199,151,104,178,186,28,93,186,129,221,183,244,184,184,120,18,219,62,26,94,50,121,198,100,163,118,23,209,18,196,47,4,210,247,69,37,219,4,151,15,179,204,66,197,82,23,38,173,147,98,98,91,207,93,13,214,156,88,16,250,58,19,229,124,36,11,229,155,68,75,112,164,70,115,154,36,74,57,8,82,5,151,233,18,155,70,41,44,12,183,229,93,71,112,132,55,48,66,146,89,246,238,39,172,178,200,206,36,80,126,187,52,62,54,16,162,33,223,163,199,141,125,255,168,125,19,146,230,144,64,198,251,166,225,141,15,74,75,96,73,157,180,80,185,55,152,90,145,173,208,24,160,195,161,55,24,189,74,91,135,54,82,122,59,61,32,32,112,84,205,164,84,22,196,126,195,173,230,185,130,92,45,27,62,247,1,57,214,164,9,23,205,90,130,59,44,148,236,113,119,28,74,139,82,60,21,251,251,254,239,97,248,165,16,35,241,20,205,159,252,243,222,182,247,31,124,240,191,46,108,211,131,80,124,132,95,126,126,42,190,9,68,201,92,153,50,45,124,5,36,222,41,199,82,144,255,145,189,119,180,111,239,155,11,192,240,159,129,156,99,66,16,52,162,185,80,82,85,248,104,101,200,175,137,119,66,19,171,155,80,177,56,136,202,0,201,27,2,67,183,104,87,62,195,198,124,168,139,205,173,165,212,75,156,190,38,213,55,80,203,58,86,243,130,242,203,96,88,9,90,28,41,95,193,6,84,84,41,166,156,104,142,81,189,99,209,213,81,50,150,181,105,112,162,48,152,145,165,114,19,155,76,10,252,221,228,90,88,88,123,128,55,123,83,26,139,126,149,57,198,65,3,144,104,228,8,171,150,56,92,118,55,209,135,229,51,45,2,36,118,137,104,184,98,77,146,98,49,174,5,157,27,240,154,122,190,141,9,83,235,136,12,229,254,98,137,21,103,164,232,181,251,131,53,203,11,230,228,245,141,146,92,97,190,3,93,81,183,52,169,230,86,109,96,59,10,10,0,149,193,249,50,98,10,219,96,239,32,78,57,201,70,201,117,50,42,165,171,97,29,8,5,142,64,230,138,36,36,59,254,170,53,17,189,163,236,196,112,92,192,253,7,89,172,66,102,62,178,84,45,87,30,60,6,139,238,5,8,2,169,146,121,186,112,146,9,208,138,9,86,165,1,249,35,1,174,63,72,37,149,49,53,139,132,232,128,167,9,122,36,26,202,160,132,121,112,57,25,243,210,226,118,248,23,131,46,137,152,173,18,253,48,168,118,158,189,219,160,50,91,71,190,207,241,145,232,242,9,24,119,169,130,243,77,150,31,19,227,48,146,243,225,16,86,83,181,43,139,100,144,60,58,60,12,251,240,77,52,165,117,176,59,11,131,82,117,91,75,212,107,203,112,52,30,149,3,5,231,209,52,149,138,167,6,82,95,172,162,245,27,148,167,34,85,156,253,10,14,217,136,50,43,116,25,79,237,212,112,203,29,132,144,101,132,157,76,10,13,226,34,5,162,98,230,78,132,152,192,104,186,215,8,67,107,77,13,68,153,166,1,95,129,52,248,58,124,200,224,65,10,201,205,50,37,243,11,195,18,76,75,39,209,132,34,231,52,41,228,93,67,71,28,72,108,54,242,201,37,212,251,196,20,148,40,182,50,71,37,213,55,239,68,228,233,11,236,226,10,200,176,140,29,17,89,26,101,153,186,138,75,160,173,151,171,136,107,237,153,95,58,195,165,209,124,166,69,192,75,220,17,59,220,242,166,20,150,11,113,59,227,222,175,153,202,39,156,248,164,178,43,1,44,1,65,169,239,10,115,115,33,11,49,73,174,85,165,53,13,179,150,17,168,191,111,245,119,127,221,179,31,63,21,63,236,253,184,244,252,97,238,7,218,129,95,49,247,238,218,201,246,151,38,131,93,77,150,14,34,241,92,15,177,230,63,88,222,188,209,180,44,122,220,248,49,236,93,212,88,147,225,175,5,246,182,157,106,138,101,248,151,235,165,89,34,79,106,34,151,177,216,210,157,107,149,231,9,68,184,38,198,37,80,15,233,42,50,228,116,41,44,149,169,84,4,119,20,183,19,84,123,179,60,131,123,174,31,24,66,205,58,59,21,236,109,137,214,139,161,10,169,26,230,67,93,226,195,184,192,43,51,177,164,249,10,81,87,188,86,89,172,154,149,10,116,4,147,103,75,116,72,16,155,110,111,36,207,179,65,101,201,101,22,187,132,198,158,194,19,104,193,120,1,228,144,37,127,164,73,35,25,12,141,203,50,142,214,142,168,28,117,72,44,42,232,86,225,193,52,99,63,238,221,42,190,107,131,74,57,214,89,175,96,208,10,239,5,217,155,86,48,94,97,229,67,39,45,24,69,91,97,226,169,154,73,161,174,201,141,142,148,156,22,197,92,90,192,224,65,0,217,8,178,191,123,174,205,138,220,176,139,83,52,98,97,118,115,248,106,156,164,41,145,174,13,78,241,134,22,174,32,195,132,199,139,36,231,19,139,92,22,164,196,62,125,55,146,3,44,24,157,173,36,230,164,2,182,117,97,122,83,44,8,41,25,78,224,96,33,189,21,9,174,248,56,248,109,108,146,130,19,178,97,100,66,229,185,206,237,86,103,186,224,211,108,145,75,106,133,173,172,37,47,92,66,44,76,76,28,60,199,102,197,123,236,217,64,220,22,190,145,24,244,97,136,145,170,242,230,87,73,54,2,6,113,53,235,181,130,212,225,197,167,212,224,200,200,76,53,102,214,240,242,169,99,184,254,40,142,116,102,146,145,227,155,236,163,5,197,32,136,5,102,113,13,62,179,208,144,93,178,254,164,17,155,5,133,150,43,136,27,80,9,58,253,179,214,224,232,117,88,4,226,236,124,80,185,244,70,22,137,25,47,112,78,163,102,50,43,146,24,22,182,105,155,130,34,31,158,247,97,80,87,123,92,166,41,65,101,2,125,0,168,12,218,172,50,208,227,144,195,172,186,98,55,151,110,113,213,253,26,179,75,145,107,53,250,90,163,92,70,134,145,74,34,39,72,219,53,147,17,78,103,80,101,159,100,40,36,64,214,6,116,184,165,90,215,200,78,238,128,223,166,229,88,242,237,88,206,84,106,187,145,21,230,90,101,112,64,1,154,66,206,82,122,229,99,58,197,154,109,194,163,152,227,235,43,26,0,254,254,44,215,144,11,34,120,208,206,141,202,33,181,153,168,250,235,159,77,173,252,60,135,255,130,159,104,93,206,119,245,3,108,223,96,64,218,57,202,158,118,225,115,249,213,91,200,209,40,87,198,44,141,78,103,133,2,188,172,115,90,151,180,134,75,32,13,152,1,219,8,83,198,211,202,130,109,243,0,40,86,213,65,14,183,16,180,198,114,27,88,115,99,5,68,136,61,206,69,151,209,167,86,53,29,222,140,16,150,0,12,219,165,6,197,169,156,169,230,234,41,171,98,146,37,199,80,104,145,112,109,133,74,15,210,164,5,47,158,182,205,13,166,7,151,22,208,9,164,122,230,146,215,71,1,50,193,131,80,199,167,85,40,212,7,76,124,67,127,5,107,131,201,68,161,76,113,129,191,86,184,166,106,102,199,195,103,225,119,253,114,200,227,153,114,120,193,51,61,23,79,158,125,68,225,50,168,82,68,12,85,187,11,14,84,142,157,71,235,230,119,233,26,128,183,52,130,127,147,105,39,22,115,54,211,109,54,252,182,52,240,121,128,2,70,70,109,89,184,169,48,56,41,43,157,34,40,32,222,30,15,196,119,42,119,22,222,96,39,106,252,36,133,21,122,175,18,162,219,83,160,113,94,213,3,64,134,18,24,63,43,246,225,34,173,239,181,157,17,159,20,151,111,173,162,50,151,224,181,15,149,142,81,14,186,236,156,126,215,58,233,28,95,180,122,175,206,223,180,79,7,151,254,9,198,242,189,197,20,185,128,153,156,207,229,48,85,222,111,196,195,22,20,33,9,85,210,120,56,180,67,203,169,157,144,86,3,193,113,190,39,107,252,63,40,59,14,41,134,127,163,15,200,109,254,223,135,135,53,255,239,253,189,71,143,238,253,63,190,200,207,189,255,199,189,255,199,189,255,199,189,255,199,189,255,199,189,255,199,189,255,199,93,252,63,56,187,33,112,70,255,52,62,32,248,222,16,191,6,126,32,192,109,86,128,173,56,94,172,46,129,69,207,150,179,186,210,84,156,41,178,137,121,55,56,5,35,86,68,179,204,51,150,210,160,106,10,203,21,176,208,189,160,82,254,190,152,110,255,163,148,41,154,19,194,74,122,97,181,43,120,142,201,44,78,73,38,125,18,80,28,173,14,98,181,132,199,83,113,217,184,11,111,219,184,180,12,51,87,128,74,82,21,8,231,255,20,126,218,191,215,207,58,254,191,200,203,248,183,242,253,252,115,11,255,255,248,96,247,160,238,255,189,119,184,123,207,255,127,137,159,123,254,255,158,255,191,231,255,239,249,255,123,254,255,158,255,255,151,231,255,127,151,252,127,200,42,125,246,0,209,62,12,251,217,115,255,93,226,184,117,183,111,248,176,132,218,3,246,197,7,107,45,153,212,12,101,63,15,156,30,145,231,159,201,57,36,209,95,100,114,70,69,132,236,190,176,173,23,108,182,224,211,109,247,175,148,19,101,154,110,122,120,70,225,181,25,42,97,202,249,92,231,206,108,152,97,126,153,106,140,101,221,43,24,148,233,88,76,11,170,22,240,20,40,160,124,219,119,139,90,97,134,10,115,70,161,107,219,200,62,206,41,121,173,201,162,30,223,105,233,189,247,124,96,159,65,216,9,122,182,200,36,71,43,113,25,109,24,172,232,46,1,164,124,50,137,9,99,71,3,97,10,215,67,82,212,121,6,198,98,53,130,115,208,227,245,231,176,33,108,147,191,160,112,211,20,223,217,79,255,202,166,48,146,112,0,53,224,155,26,102,172,25,149,80,128,146,32,226,195,12,124,76,153,166,144,225,7,50,102,53,93,206,46,251,219,80,235,84,73,242,42,143,203,220,216,83,166,67,34,132,211,57,202,157,204,117,48,38,181,184,202,123,238,62,5,235,244,251,57,87,28,66,59,72,80,83,219,14,115,45,243,68,102,133,29,96,232,124,64,100,182,224,47,4,165,1,83,198,185,66,220,233,164,104,163,248,160,0,30,127,78,240,109,40,236,178,207,0,181,99,123,32,124,236,74,51,244,194,93,183,219,232,155,11,113,90,166,41,14,107,191,113,21,180,93,21,184,106,111,170,41,19,244,167,79,240,84,92,247,253,213,221,73,10,14,186,115,201,132,106,153,239,131,213,221,233,152,195,254,80,158,221,254,167,90,146,124,229,212,76,135,130,238,132,248,248,101,181,88,249,242,16,206,232,69,167,132,67,156,36,166,192,13,180,168,85,45,102,206,5,77,46,221,46,95,82,121,81,240,119,40,116,38,84,86,206,216,203,163,8,138,147,81,118,56,62,44,190,247,225,109,2,51,98,153,5,140,224,199,113,171,10,4,52,187,180,51,92,70,27,22,138,0,21,8,195,78,43,184,114,122,126,114,114,241,93,235,228,188,45,158,139,93,119,181,221,250,105,105,55,185,156,207,85,46,100,14,225,49,75,222,163,254,238,221,229,62,84,71,135,102,50,207,229,194,223,9,191,255,4,117,111,105,190,143,209,47,7,29,142,65,206,68,255,250,218,153,223,255,103,141,254,167,112,137,107,63,131,10,232,150,248,255,195,195,199,75,250,159,71,251,15,239,245,63,95,226,231,94,255,115,175,255,185,215,255,220,235,127,238,245,63,247,250,159,123,253,207,175,209,255,56,86,233,179,171,128,92,18,245,223,161,2,132,79,208,94,17,247,231,58,161,122,128,9,120,107,47,85,99,128,207,127,6,65,59,135,96,0,136,102,227,26,13,205,170,195,248,167,148,134,128,87,112,85,170,99,212,208,224,80,92,216,33,185,118,21,20,231,58,158,10,89,136,243,193,145,152,37,163,12,158,48,240,255,20,223,202,172,180,111,223,94,83,236,61,121,188,219,12,66,111,82,53,47,146,88,188,202,213,68,231,137,204,124,149,9,84,108,168,247,5,4,36,208,139,180,162,221,80,198,87,55,50,31,65,48,18,100,124,214,153,211,243,88,254,135,146,168,3,167,129,41,164,97,165,169,206,38,145,56,81,114,238,23,159,43,209,48,51,37,115,53,106,8,40,161,39,237,51,44,82,37,231,160,231,194,61,41,44,234,66,108,141,130,236,228,99,72,134,86,168,124,110,153,11,228,107,74,3,254,227,226,135,253,195,237,169,46,177,16,173,196,152,125,59,195,143,155,31,231,193,236,249,238,64,203,173,80,244,203,185,122,5,248,231,91,174,125,27,254,55,216,221,125,10,255,251,222,110,195,147,39,79,158,108,239,237,111,31,236,13,246,15,158,62,124,242,244,225,147,232,9,255,124,31,137,23,11,244,161,181,207,123,92,80,152,41,42,220,236,248,77,113,163,132,202,76,153,147,229,255,70,129,134,137,98,4,240,196,169,70,242,15,189,151,71,118,176,131,131,131,39,126,77,55,55,55,81,162,138,49,220,214,124,28,219,255,219,22,81,241,190,216,130,140,247,164,196,248,164,74,27,181,66,10,103,221,126,231,239,226,210,238,212,230,214,229,234,154,9,142,40,56,55,109,47,81,25,85,92,208,209,111,194,32,86,102,223,218,90,211,18,238,196,230,238,214,179,59,23,122,32,248,38,170,176,35,233,241,72,46,106,112,146,210,205,126,125,45,83,81,92,187,185,43,157,254,92,92,55,65,161,176,245,236,183,45,242,58,42,174,237,95,31,95,35,54,43,141,138,41,121,250,210,154,15,214,174,249,109,146,29,236,139,203,87,170,232,67,89,80,251,117,203,188,76,82,53,88,62,166,151,157,147,246,160,243,166,45,198,133,3,104,93,207,63,143,11,15,245,121,231,116,240,232,80,20,73,124,101,41,238,230,230,38,126,178,53,46,162,209,205,235,100,50,61,150,5,244,219,18,127,249,139,56,216,223,18,255,43,224,187,19,125,195,95,133,123,9,164,248,109,146,141,244,141,129,97,237,21,219,219,173,212,2,136,92,3,164,117,123,143,150,47,95,48,158,29,96,239,209,161,21,170,31,237,122,178,67,213,218,207,179,228,61,143,243,228,241,110,125,156,232,215,31,242,38,238,132,216,220,196,237,217,113,149,44,182,196,118,8,210,173,184,110,71,178,91,199,35,253,41,24,9,16,99,107,9,49,14,215,34,198,183,242,90,138,75,60,218,136,10,210,219,38,111,146,52,77,76,13,49,44,109,22,51,248,70,60,23,235,59,221,114,29,196,243,160,240,79,166,110,94,148,73,58,82,249,230,150,93,100,159,246,139,166,193,109,114,149,52,236,143,109,117,138,59,145,100,133,221,7,106,139,27,177,197,165,5,236,70,68,67,59,182,131,40,220,147,135,183,236,73,7,66,68,139,40,211,55,181,109,160,111,68,166,111,196,115,81,105,119,235,202,195,133,220,190,9,153,190,137,38,170,104,91,132,196,207,54,183,42,123,81,221,15,106,110,255,216,252,232,218,31,173,93,59,157,38,243,55,171,138,163,172,58,70,95,235,196,99,236,43,85,28,121,220,216,252,228,90,39,193,254,125,164,216,137,143,61,177,79,222,39,189,119,56,153,229,159,164,101,157,124,98,16,44,203,145,24,209,248,197,114,46,31,182,127,129,226,89,31,182,127,25,201,197,135,193,47,150,113,248,240,244,151,89,146,125,120,250,139,81,241,135,31,162,95,44,219,102,47,251,135,31,191,111,160,13,80,229,74,96,127,208,41,99,212,169,47,2,130,156,200,216,242,32,163,100,146,20,134,234,148,208,92,77,1,147,129,156,132,19,54,5,204,136,65,51,48,45,112,70,63,171,92,111,207,177,206,150,101,23,110,52,143,167,100,60,69,238,208,23,91,241,236,146,105,6,70,170,137,22,37,88,43,159,112,231,205,36,82,17,125,184,183,154,243,220,2,224,44,12,92,168,24,103,107,124,223,224,98,50,222,128,4,233,5,146,153,2,222,120,179,113,62,56,106,108,61,171,124,186,129,212,153,35,83,201,170,85,232,3,68,13,3,42,145,228,103,149,115,116,17,109,105,105,20,112,183,16,19,77,243,141,196,16,120,169,198,247,141,45,123,20,153,152,231,73,134,44,213,50,106,81,21,143,96,178,185,204,141,159,8,211,163,0,119,105,121,172,24,210,241,12,117,49,133,121,33,123,16,106,94,104,37,102,9,22,1,213,89,198,70,21,91,43,83,48,52,246,119,247,30,219,215,102,239,225,96,119,239,233,193,238,211,189,135,209,238,222,247,13,194,121,35,224,111,247,92,65,173,233,157,29,1,109,1,10,157,121,126,254,97,83,216,241,130,8,126,75,210,250,96,13,110,130,21,48,100,27,165,56,134,56,93,76,15,4,28,167,43,93,78,88,74,23,195,18,186,145,204,33,22,245,135,66,119,250,221,62,92,194,205,173,21,108,115,52,211,63,39,105,42,225,238,169,108,251,188,191,51,210,177,217,121,171,134,59,30,156,157,30,87,156,223,121,149,234,161,76,47,186,0,135,217,177,64,237,4,147,108,145,106,17,242,28,119,152,50,161,9,21,193,18,151,174,102,19,255,114,201,203,34,75,108,45,156,118,121,169,176,180,75,83,228,99,232,30,172,75,199,38,154,35,53,180,43,218,223,73,147,97,46,243,5,136,4,209,180,152,165,127,132,223,184,239,22,168,192,54,40,208,29,232,41,77,100,230,42,22,15,254,244,110,251,79,179,237,63,141,6,127,122,253,244,79,111,158,254,169,31,253,105,252,253,131,72,156,36,87,234,38,49,152,229,192,110,148,63,177,18,205,182,118,188,111,245,8,203,231,61,48,226,135,203,78,191,203,236,211,75,36,106,35,250,115,115,235,242,199,77,86,45,19,69,252,73,143,240,84,236,47,219,32,209,200,121,2,135,195,159,162,156,131,240,238,44,143,14,171,229,41,254,180,127,252,167,253,99,59,199,22,36,158,24,130,34,87,186,226,247,185,136,37,68,234,89,129,54,168,222,95,84,202,241,5,39,81,175,128,228,111,171,55,142,177,72,30,148,65,178,183,0,182,217,36,89,28,178,114,216,105,37,63,87,173,135,179,70,110,195,254,43,132,183,239,151,234,227,172,46,97,116,170,179,109,87,23,232,211,10,25,69,226,148,58,226,80,212,192,101,203,41,166,193,128,160,191,54,69,146,166,152,21,47,11,231,197,186,61,216,113,195,23,225,71,197,193,88,231,86,88,103,205,70,125,95,72,120,173,214,10,250,183,168,13,180,206,254,183,152,171,207,85,254,231,54,251,223,193,227,135,143,234,245,127,30,237,62,186,183,255,125,137,159,123,251,223,189,253,239,222,254,119,111,255,187,183,255,221,219,255,254,185,237,127,201,12,92,107,151,194,249,100,70,133,10,27,207,214,182,89,25,242,247,101,108,138,159,199,18,184,152,171,127,154,80,83,251,187,139,48,37,29,134,101,31,240,213,246,53,133,44,11,233,101,156,197,188,226,19,59,46,211,116,33,124,4,40,183,179,43,14,66,49,125,20,166,235,201,47,18,103,241,11,188,3,49,23,140,243,108,222,95,209,11,22,2,169,55,37,171,215,46,193,29,247,178,146,89,150,5,54,92,196,114,42,21,74,31,68,78,176,28,212,90,219,9,202,86,88,233,223,165,163,161,68,134,228,9,203,185,92,152,105,64,52,221,16,181,0,218,42,26,179,15,108,181,51,94,42,232,139,215,203,221,178,71,236,13,218,226,76,94,206,247,82,174,57,53,220,80,58,182,23,210,184,140,240,176,141,118,18,240,73,253,91,197,147,249,165,107,33,202,12,80,6,125,112,7,239,206,218,23,231,167,127,59,237,190,61,69,231,212,229,14,232,168,28,180,63,238,158,91,250,31,250,58,7,205,199,169,150,69,208,250,229,73,183,53,168,120,54,7,141,65,124,13,26,163,49,39,244,99,14,33,175,183,62,231,230,135,107,198,62,216,175,142,125,176,95,113,82,14,161,78,222,171,81,101,240,151,157,191,183,143,97,244,71,107,59,84,198,135,14,48,195,227,85,29,134,90,167,65,235,23,221,238,137,120,46,190,89,213,148,179,190,186,198,246,5,57,125,133,41,166,150,155,79,114,93,206,35,148,25,246,25,183,116,150,46,80,109,59,82,243,92,129,82,48,24,241,85,175,123,126,102,143,112,229,145,115,94,107,223,254,77,187,223,111,189,130,67,95,121,234,195,69,129,200,199,203,123,55,104,247,109,235,149,199,94,214,207,230,156,15,103,111,229,201,91,140,14,90,183,79,207,223,216,182,43,143,221,44,159,76,223,31,205,222,202,211,55,203,199,223,247,231,191,183,18,1,76,125,13,125,183,134,149,231,111,234,216,219,103,236,221,251,6,93,222,241,74,191,157,98,246,107,25,36,13,38,85,119,211,41,170,33,44,131,9,152,187,243,71,50,31,37,153,76,147,98,17,92,125,159,169,30,24,122,186,255,34,246,141,17,168,163,86,239,184,115,218,178,124,193,106,146,160,115,7,73,64,233,171,29,187,192,58,181,78,170,212,1,128,165,228,143,156,206,109,25,93,151,71,235,181,255,251,188,211,107,31,87,201,71,176,244,181,112,244,218,103,237,214,0,122,30,132,187,235,211,176,241,51,2,132,18,226,62,170,111,26,182,170,237,82,184,195,193,87,181,135,13,187,98,100,71,160,168,194,138,245,213,247,137,154,174,124,97,15,151,218,1,34,157,247,78,154,78,212,129,4,17,241,84,205,20,214,2,241,37,33,194,0,9,210,189,193,3,193,6,185,167,226,178,1,123,128,44,134,156,39,6,36,254,122,221,61,167,9,173,228,99,176,61,47,202,60,101,242,200,121,221,178,145,122,95,77,0,74,180,88,92,90,118,35,194,71,250,242,206,192,226,218,115,83,224,56,83,180,113,168,247,98,239,25,88,161,32,71,44,89,122,200,98,151,105,151,103,22,18,217,187,3,128,185,47,176,59,17,233,224,190,81,37,68,153,22,42,167,112,55,203,135,129,28,156,47,133,190,109,80,4,13,53,33,66,254,91,152,142,39,75,167,13,86,161,26,106,252,100,116,230,242,96,236,134,172,70,16,33,196,7,80,77,114,172,41,159,45,85,101,95,125,255,56,29,38,246,244,81,77,46,34,173,109,9,13,242,5,142,55,11,202,40,218,111,137,55,241,45,63,206,64,66,59,156,40,96,247,42,155,101,155,96,152,137,197,147,74,172,84,168,44,251,148,237,62,248,45,60,222,10,6,113,61,143,247,176,178,117,245,133,86,247,174,18,143,19,180,191,243,14,174,37,58,191,117,179,62,172,17,45,176,81,179,26,124,40,139,66,198,83,174,251,226,74,7,1,230,129,20,30,92,247,166,80,69,236,119,129,230,14,196,18,156,225,1,102,171,197,152,83,151,96,102,88,38,105,177,157,120,88,55,249,23,202,123,35,18,162,39,24,43,58,47,116,142,164,109,171,233,178,59,3,13,157,90,33,213,207,224,172,164,151,141,153,156,95,168,172,200,23,72,0,233,5,162,90,24,52,93,83,36,65,217,33,164,126,86,154,170,229,211,169,142,141,131,113,50,156,72,206,147,104,90,20,85,58,187,66,216,114,251,129,39,78,20,40,201,160,46,107,182,8,138,146,140,125,105,5,12,49,155,231,201,44,177,164,173,201,214,24,139,245,57,150,28,129,84,196,28,132,230,111,56,142,93,151,222,169,157,193,205,36,59,145,91,63,86,255,88,154,31,131,246,106,123,101,10,200,2,13,49,192,136,180,56,26,118,115,182,224,186,246,33,234,216,166,120,95,248,41,111,65,24,169,35,14,136,178,112,71,241,46,186,212,72,114,9,141,41,83,81,37,99,18,240,84,116,155,9,31,233,175,75,232,190,15,7,213,127,119,58,104,253,253,226,172,215,29,116,247,153,97,170,55,61,88,106,122,176,62,84,110,141,253,167,186,229,191,209,198,112,91,254,159,199,123,251,245,248,175,195,71,7,247,246,159,47,241,115,111,255,185,183,255,220,219,127,238,237,63,247,246,159,123,251,207,151,182,255,88,129,152,248,12,16,209,29,199,40,54,51,157,113,177,167,173,64,60,55,138,21,248,88,161,115,92,166,228,208,42,212,108,168,70,192,86,186,97,92,185,145,203,58,63,215,202,22,151,222,53,18,230,78,101,172,140,119,108,189,81,16,101,3,9,110,48,5,78,153,152,169,24,170,226,70,41,38,227,62,167,136,159,116,131,244,9,156,217,192,78,128,117,229,2,249,56,8,173,49,138,249,96,195,78,77,160,103,72,178,201,184,76,225,161,179,164,38,201,234,122,40,129,245,103,22,34,149,241,21,187,205,201,97,2,58,34,11,182,42,84,92,4,229,111,178,176,52,31,241,160,16,7,243,105,96,72,76,56,147,11,73,121,76,192,29,13,9,191,31,222,146,92,170,177,198,237,195,242,69,216,211,74,112,50,205,149,28,45,234,224,254,203,132,7,242,174,126,246,232,64,190,58,159,61,56,144,6,14,234,235,230,226,18,13,51,151,119,74,7,114,12,109,107,9,65,88,89,192,163,6,141,66,1,188,158,187,38,252,59,76,86,180,18,72,48,7,221,13,198,151,182,233,45,32,250,54,21,203,165,253,212,3,24,252,121,43,124,160,149,191,27,124,29,219,180,6,31,155,106,120,76,223,38,132,15,189,52,29,124,193,159,183,194,87,126,2,128,231,119,129,240,124,53,136,101,13,198,242,83,128,4,177,253,206,155,72,98,251,250,67,14,68,251,234,38,30,236,87,54,145,255,188,211,38,222,21,192,243,187,64,120,190,26,196,178,6,99,249,41,64,14,181,78,239,6,226,11,173,151,242,17,89,106,66,133,185,199,50,53,150,44,240,232,174,121,8,42,104,175,29,160,254,175,91,193,68,124,186,27,160,232,69,127,11,66,6,141,42,69,84,106,41,175,42,10,238,91,247,114,81,40,115,199,205,180,77,111,1,209,183,169,108,161,253,52,216,67,255,231,111,75,131,100,202,225,76,143,202,84,153,157,34,159,199,219,44,131,239,68,147,228,163,250,142,79,248,185,69,255,179,187,251,248,241,31,246,14,31,238,237,238,61,220,127,180,247,232,15,187,123,143,30,29,220,251,255,126,145,159,73,82,140,146,252,169,136,162,29,250,223,36,41,118,24,37,160,140,100,154,238,172,195,146,127,13,31,248,127,231,159,181,247,223,9,226,157,211,87,209,108,244,91,230,184,77,255,187,191,191,91,189,255,251,187,7,187,247,249,223,191,200,207,96,42,179,43,177,208,37,60,80,11,93,82,74,9,101,10,172,21,75,25,77,173,36,221,59,59,250,15,177,177,241,214,74,199,105,172,103,20,88,56,159,231,10,42,50,64,130,16,80,52,162,194,208,41,241,154,84,29,205,190,169,195,18,52,140,34,181,242,50,165,238,44,135,179,164,128,152,169,196,24,40,219,141,122,65,248,100,102,127,71,131,137,41,39,19,101,216,8,6,95,128,250,49,212,52,54,197,56,121,143,19,77,168,0,155,68,189,192,88,201,162,204,81,147,144,24,215,75,200,100,6,73,60,184,218,173,221,12,80,71,74,202,11,171,70,149,213,136,73,9,117,135,181,152,170,116,14,205,135,10,226,192,230,50,47,146,56,153,219,189,240,185,70,48,205,236,89,170,164,81,194,10,187,168,73,196,81,98,153,43,244,133,164,8,125,63,19,20,104,29,137,153,188,82,2,115,98,104,210,185,98,13,85,123,105,197,84,229,42,18,111,21,150,123,228,48,167,66,139,27,157,95,129,145,205,174,196,194,88,104,28,10,38,39,176,24,112,78,105,251,31,27,27,127,252,163,120,129,144,4,199,34,51,60,153,141,141,57,46,35,0,106,42,11,24,31,180,6,185,186,78,212,13,149,234,160,73,30,152,250,9,189,108,253,55,158,140,43,238,141,231,78,39,3,106,129,107,157,140,66,16,208,145,8,219,57,85,72,186,64,36,181,83,3,238,178,110,154,215,55,147,9,22,15,201,31,24,138,252,122,59,85,25,0,60,82,49,157,35,78,227,86,217,20,180,74,191,219,134,246,251,169,216,216,22,125,149,218,177,45,226,235,121,14,152,159,202,161,74,141,203,251,11,195,208,106,44,146,24,81,2,138,253,163,76,226,171,116,129,85,116,21,67,58,76,213,12,215,161,211,107,37,18,168,72,105,180,206,236,191,115,109,76,50,76,85,100,103,110,7,201,81,220,60,162,72,10,204,11,19,235,44,78,12,93,203,56,46,115,89,168,116,33,76,57,155,201,60,249,153,162,148,105,198,72,180,96,143,209,234,121,45,39,165,178,72,51,194,138,161,118,234,6,181,108,8,157,139,6,164,199,109,68,98,163,147,5,115,179,169,27,206,149,182,45,172,72,77,247,39,104,198,14,35,188,112,123,20,42,131,48,61,5,97,209,176,107,84,78,209,252,255,236,189,7,84,19,75,219,56,14,8,138,96,193,6,118,87,84,4,13,160,72,87,20,16,4,4,4,1,69,84,196,144,44,16,13,73,76,161,88,1,65,65,154,5,68,233,34,8,22,138,133,222,236,215,114,5,187,82,45,164,128,34,216,145,162,252,207,206,238,38,11,122,189,247,125,191,239,188,255,243,251,206,155,115,174,55,108,102,103,158,121,230,233,243,204,51,64,94,96,137,54,4,145,49,96,255,193,88,65,19,114,196,122,35,12,100,12,121,178,105,176,23,61,80,92,187,25,221,125,15,244,101,113,153,190,232,62,6,205,151,69,150,220,34,140,99,70,65,19,28,193,4,251,0,8,196,28,46,204,226,24,75,186,161,49,176,153,65,62,8,121,48,7,237,169,96,221,144,196,165,124,176,58,54,216,170,75,86,154,136,6,95,132,229,48,250,192,214,218,143,198,102,50,208,157,98,201,101,61,198,16,27,166,195,126,228,129,79,9,2,22,187,143,152,225,13,113,64,1,11,18,228,201,102,250,115,96,54,73,204,21,126,48,155,35,206,134,0,99,129,43,40,233,76,111,99,236,238,120,54,12,66,172,226,161,96,188,1,231,167,85,230,250,32,180,132,116,130,87,99,70,47,143,39,34,204,31,39,88,144,0,64,225,226,247,203,139,119,230,65,7,206,20,54,12,51,56,62,76,46,7,161,56,14,248,19,98,195,20,38,27,153,25,7,0,135,243,131,228,226,115,206,223,188,54,120,117,33,5,76,22,123,194,16,139,73,167,97,75,226,197,166,193,12,42,130,124,87,60,169,4,242,6,183,198,162,167,10,192,117,234,24,233,193,132,181,145,244,14,112,11,174,6,103,178,48,38,133,253,96,118,32,126,188,217,155,13,168,5,21,181,16,122,134,24,27,20,37,70,252,192,41,177,127,45,32,146,157,128,176,71,196,11,65,36,58,58,113,6,170,99,76,204,99,226,12,236,61,226,18,73,172,135,126,33,220,33,71,39,241,170,254,181,96,199,245,214,207,170,80,11,178,198,9,6,212,123,39,168,105,244,2,84,0,60,27,246,6,73,140,222,131,166,48,88,53,194,190,63,43,69,201,27,198,131,164,32,144,250,96,166,20,38,96,7,14,190,70,18,237,3,126,198,247,233,208,27,160,255,153,148,65,95,228,6,162,215,75,251,162,54,200,128,126,48,22,250,73,208,227,122,7,187,66,30,38,51,232,52,6,204,65,241,129,149,213,135,25,148,192,65,212,3,216,224,223,92,33,46,204,65,192,150,32,4,84,103,67,232,121,176,214,0,191,250,144,145,233,66,76,79,63,26,147,199,65,25,28,3,143,204,128,216,60,6,196,64,132,11,29,147,70,216,26,113,126,171,250,192,216,142,78,191,192,7,139,205,164,32,211,199,90,12,148,118,191,90,82,71,167,127,69,173,161,147,6,25,10,156,127,160,215,208,59,210,81,181,6,210,2,2,85,193,36,49,205,230,232,244,111,170,181,129,96,252,235,122,12,82,128,32,68,245,144,57,88,192,136,152,179,32,81,103,112,0,139,78,6,249,69,129,40,75,18,155,161,245,225,16,100,147,217,200,210,33,61,218,19,127,7,153,133,12,238,47,213,153,255,0,138,66,187,133,169,152,76,243,151,252,34,190,82,25,166,66,52,46,54,138,51,5,17,123,76,47,76,169,26,15,84,187,94,60,6,94,22,0,204,11,200,4,176,222,216,150,60,25,92,232,47,185,163,159,56,41,108,4,23,24,88,139,131,122,230,162,79,37,208,81,17,129,139,81,191,216,34,196,148,18,186,206,94,98,34,3,149,8,252,192,141,253,20,152,13,88,118,160,13,40,190,111,238,23,9,108,168,9,68,251,21,213,104,13,188,133,110,5,45,0,230,64,179,22,234,44,66,229,249,114,166,175,47,143,129,47,9,2,227,114,38,3,1,16,125,240,43,169,254,215,206,5,16,113,131,251,163,16,250,211,130,220,152,60,192,215,192,183,67,44,30,52,61,31,89,1,54,147,231,237,51,56,231,197,135,204,96,192,116,14,34,109,157,81,109,2,16,6,46,191,198,23,145,40,230,127,2,136,74,227,80,120,32,255,1,69,249,74,38,141,1,33,93,112,97,138,15,2,40,125,16,204,232,193,146,255,6,148,254,195,159,127,20,255,241,160,48,254,39,33,160,191,141,255,46,248,41,254,99,160,251,223,250,239,255,145,207,95,174,191,157,205,114,203,85,206,150,255,27,99,252,126,253,117,244,23,46,210,27,20,255,55,88,160,175,243,223,245,255,79,124,160,191,251,152,177,200,20,31,24,178,163,81,96,6,7,86,248,77,203,181,168,87,9,233,104,45,32,137,107,117,233,44,88,160,251,151,47,17,106,54,145,193,48,32,141,130,142,14,197,209,86,64,94,116,177,116,178,23,103,194,89,216,184,216,56,172,2,217,103,32,201,10,114,178,116,116,114,176,88,179,28,121,76,2,173,44,108,156,49,185,229,176,10,116,176,80,11,178,32,30,245,192,160,81,197,102,164,10,113,124,200,116,58,72,118,193,204,9,182,175,216,78,199,115,30,17,99,140,199,129,73,98,79,31,88,134,88,87,224,224,227,128,12,85,201,145,0,207,64,200,25,198,12,159,133,98,109,107,36,62,32,131,71,198,6,195,197,100,255,4,152,36,67,147,233,207,128,217,232,73,38,46,141,27,8,145,121,92,31,38,98,9,131,178,112,104,63,191,122,131,139,22,2,132,188,217,100,73,173,56,12,15,4,0,96,111,50,29,178,4,93,255,4,4,184,201,6,247,90,200,104,17,95,28,10,196,60,167,211,177,110,208,76,79,240,19,13,183,244,128,235,200,164,163,217,183,216,31,116,0,52,122,245,19,27,233,159,10,179,129,105,0,14,103,33,31,172,33,158,34,138,120,213,96,64,212,196,2,102,7,143,205,98,114,96,142,4,171,226,5,199,215,72,21,235,69,21,59,196,165,78,211,64,95,101,250,195,108,18,68,165,129,176,4,40,168,140,126,39,1,7,144,204,227,0,195,15,235,5,253,9,96,128,13,249,146,25,100,111,24,143,1,0,231,2,5,140,4,249,99,231,188,60,3,81,232,65,140,137,77,196,12,90,1,141,201,134,212,105,52,13,116,121,56,62,52,22,122,176,221,139,27,8,177,96,54,5,233,90,93,111,193,28,13,212,102,102,227,135,173,240,142,120,92,80,26,14,248,212,62,100,54,204,193,123,164,105,64,158,48,3,246,162,81,104,100,250,192,222,9,112,74,150,220,141,201,83,133,212,17,119,200,141,201,99,171,106,16,87,157,60,32,111,140,201,134,136,244,129,117,0,7,192,108,10,13,56,92,146,196,87,140,206,112,139,158,198,249,153,212,208,163,79,170,232,166,193,32,74,99,177,97,47,152,205,70,235,92,251,162,238,16,25,132,180,137,158,1,7,95,224,223,239,48,224,89,187,132,180,108,210,192,168,52,214,13,218,128,132,243,191,23,205,155,135,221,251,4,82,169,36,160,163,101,252,126,6,93,188,7,130,58,28,96,227,129,205,244,133,124,97,196,168,70,12,95,156,65,217,100,6,71,18,192,67,72,25,121,66,39,227,222,36,25,59,25,6,186,27,180,133,130,245,241,83,188,194,151,5,252,82,188,40,32,152,38,86,146,14,113,87,7,132,225,9,210,11,45,27,136,46,26,151,137,103,105,195,84,26,25,63,233,143,79,219,149,201,222,250,147,80,240,103,178,183,2,136,129,28,66,40,77,194,2,52,6,62,13,49,3,160,168,195,166,229,75,70,92,106,63,50,141,14,74,232,161,252,79,144,75,36,232,167,82,147,98,185,48,48,99,93,44,222,48,159,27,156,37,66,196,10,225,128,24,14,45,214,133,58,153,129,251,104,16,141,144,141,142,185,51,102,44,22,204,160,210,2,32,79,152,206,244,215,144,96,193,2,102,211,252,208,115,155,8,66,56,170,131,41,0,25,227,215,56,192,102,143,245,132,226,0,7,220,147,204,65,22,143,1,88,145,152,126,142,202,42,100,40,113,194,42,122,184,72,34,12,96,42,141,203,100,35,236,206,134,253,104,28,52,56,69,102,48,152,92,113,164,138,78,246,100,178,241,191,36,201,248,68,110,194,58,19,231,174,144,208,90,180,254,62,76,58,96,10,136,201,166,121,211,24,100,250,47,214,252,103,121,140,203,41,175,1,236,79,130,6,163,15,195,30,122,152,22,172,29,232,158,131,95,198,232,75,166,137,249,19,102,145,217,128,82,16,188,128,105,248,194,108,152,30,8,209,105,140,173,0,113,158,52,6,160,19,6,217,23,214,192,23,29,56,190,94,100,10,80,18,36,130,142,20,35,245,39,160,64,24,156,233,37,89,245,229,132,200,231,47,87,124,48,15,136,89,150,48,158,24,129,24,195,225,186,84,12,7,210,217,128,53,1,52,76,197,44,17,188,39,108,103,1,188,197,100,255,37,240,36,2,83,112,17,169,207,100,144,233,116,92,108,99,33,70,148,53,112,187,3,187,86,0,132,162,193,198,130,4,60,44,50,51,200,172,192,87,153,141,213,129,253,107,109,65,52,84,36,113,106,38,3,242,132,125,200,116,47,136,233,245,215,198,203,63,211,246,144,170,120,78,170,88,95,168,190,39,110,77,131,24,38,155,201,160,81,72,200,42,120,146,233,128,142,240,163,27,3,227,18,8,23,16,145,14,75,16,133,224,137,203,25,144,232,229,135,232,224,223,169,34,177,236,34,142,193,100,16,96,130,124,201,52,58,184,211,148,198,225,114,72,3,78,18,225,166,16,186,179,195,33,138,112,108,43,144,77,166,108,149,236,253,96,28,132,104,62,212,90,17,219,90,68,164,147,8,98,100,0,21,16,176,13,110,232,195,98,58,216,198,180,100,3,30,39,16,18,65,53,193,1,56,18,6,206,21,167,71,10,147,193,97,209,40,60,38,143,67,15,132,124,201,236,173,136,232,99,75,172,35,220,228,130,57,52,111,6,144,253,52,6,88,35,128,216,95,82,34,8,238,174,98,114,33,50,68,228,85,45,213,159,89,120,144,125,45,158,54,206,129,127,107,242,16,17,136,200,71,223,65,131,130,0,187,39,182,19,5,3,73,238,25,56,96,28,9,19,114,224,109,60,152,193,165,35,195,82,152,108,22,19,85,215,88,194,61,142,93,84,16,233,104,65,86,136,89,133,12,43,57,130,135,91,86,144,51,143,80,230,248,47,156,25,2,155,17,165,50,76,166,248,64,4,4,129,220,2,207,64,212,138,3,118,129,27,147,7,145,17,11,143,5,115,121,100,58,78,126,254,76,54,157,234,79,67,108,13,6,147,161,9,86,158,67,243,3,127,106,82,124,200,108,111,196,113,98,6,146,233,220,64,77,47,54,12,147,32,26,155,13,251,49,41,136,32,255,73,155,99,254,223,128,125,85,18,98,14,178,16,58,254,73,210,73,196,57,139,231,73,167,81,232,129,8,161,178,232,228,64,146,228,9,11,102,163,170,150,3,158,96,134,5,209,111,35,154,249,98,89,12,140,229,159,70,252,133,58,7,178,5,93,160,69,132,5,114,36,35,66,247,255,192,234,168,195,1,160,40,56,153,3,113,184,56,51,162,7,226,80,135,72,3,98,161,115,37,172,158,47,121,43,76,194,182,18,200,84,24,7,8,248,209,76,112,18,26,220,219,75,167,147,176,127,209,141,86,146,164,226,56,34,7,48,67,25,179,10,129,152,193,103,6,246,169,193,26,225,163,146,89,44,58,56,119,194,160,7,162,88,70,100,23,6,26,56,163,200,193,218,18,38,231,25,136,118,66,196,174,88,110,226,123,41,52,192,157,94,108,26,195,91,188,71,65,195,117,31,145,241,213,57,26,16,153,142,221,144,4,28,64,95,79,26,131,76,72,125,160,177,7,191,128,79,8,191,77,26,16,32,151,137,25,121,3,129,195,134,240,71,150,2,215,117,224,252,187,27,147,39,246,133,56,92,26,23,161,105,241,162,112,105,222,216,222,128,55,25,249,25,8,57,204,113,87,151,40,44,177,109,205,102,114,56,154,0,97,200,52,176,236,12,244,111,176,113,77,39,251,115,120,52,46,50,85,58,236,141,42,1,108,123,209,85,98,95,131,83,66,3,164,226,239,4,28,208,9,40,224,28,204,213,150,244,67,56,197,25,136,79,11,95,15,95,96,169,114,125,96,212,20,27,72,137,184,201,132,59,163,24,167,224,142,134,132,199,48,149,135,91,85,168,118,64,88,20,89,61,156,86,200,226,116,2,244,54,33,148,248,196,216,5,37,79,232,48,21,21,5,186,90,131,78,228,162,27,49,190,228,64,66,198,200,32,41,68,97,178,104,184,109,51,64,30,253,198,202,67,11,50,4,2,143,141,231,251,243,233,103,204,16,26,224,54,99,25,7,191,150,100,164,65,39,162,37,164,229,11,195,127,125,64,218,88,65,236,87,105,160,51,229,113,184,144,55,2,47,2,30,234,111,176,97,10,141,69,3,197,205,137,166,175,216,59,68,62,63,77,148,12,244,195,96,79,98,49,80,163,248,152,158,132,49,209,192,141,196,148,6,167,230,192,142,35,19,162,144,217,8,9,177,153,190,52,6,204,192,189,71,14,97,120,68,196,137,73,26,108,157,129,61,93,236,216,51,210,207,192,145,41,132,145,209,115,222,226,187,198,8,46,60,126,133,218,224,201,17,6,22,15,40,33,8,18,194,97,18,237,72,194,168,155,132,136,69,42,140,216,77,36,130,49,1,72,148,43,97,55,108,110,104,8,226,23,240,12,22,169,3,45,55,84,122,226,125,0,224,168,76,96,208,178,176,189,82,112,37,87,32,216,155,148,40,46,8,179,224,7,79,116,32,210,168,26,120,209,14,176,254,226,141,114,50,164,186,202,193,197,102,185,165,42,4,42,224,32,248,6,137,112,232,24,224,84,183,100,28,34,119,17,68,192,47,56,229,39,204,130,245,34,116,133,187,158,100,144,137,2,124,76,9,209,193,191,68,43,34,148,200,52,6,76,68,63,38,212,128,100,64,39,2,166,64,250,39,120,37,116,243,107,12,255,18,175,128,216,200,92,136,14,147,57,224,18,124,66,55,120,121,44,49,183,162,7,93,141,37,167,57,49,24,37,184,150,96,104,0,85,113,126,11,195,98,162,48,31,64,100,68,190,30,148,7,74,243,146,200,25,50,184,124,73,172,1,127,238,159,201,38,253,140,101,50,110,235,17,162,92,152,111,240,11,44,121,13,226,20,96,64,248,193,108,116,177,184,62,52,54,85,19,153,100,160,120,109,240,28,24,172,98,40,126,23,33,240,165,57,63,163,153,176,222,192,120,64,93,105,113,144,143,76,39,56,175,12,52,57,97,0,118,0,111,161,25,41,3,98,243,98,181,65,166,82,145,239,108,196,223,33,82,36,161,23,28,116,12,67,255,132,19,72,40,246,57,52,234,0,210,97,99,133,114,200,84,42,204,160,242,124,113,179,117,0,197,224,130,5,245,255,240,229,28,44,211,208,212,27,44,136,65,166,255,154,153,64,180,10,187,197,132,195,101,243,6,211,31,138,152,191,218,183,248,37,138,36,94,5,48,91,65,176,30,53,0,6,5,190,8,75,129,116,34,206,245,145,128,204,100,67,84,154,23,184,204,133,96,229,254,194,130,151,132,246,126,177,101,132,118,67,216,43,98,122,253,2,26,146,132,109,188,128,179,24,248,23,174,8,49,58,39,102,37,208,31,50,52,33,154,39,1,224,167,221,170,1,90,88,108,117,83,152,190,168,41,13,110,121,145,8,117,130,167,50,200,19,24,176,32,122,90,104,226,8,7,143,113,17,173,64,142,22,180,134,65,135,57,28,176,104,112,0,139,78,163,208,16,247,23,244,72,216,32,17,199,55,2,7,91,145,132,96,22,33,140,245,151,161,43,137,165,239,134,102,211,12,8,228,160,166,158,39,49,250,252,175,184,102,120,41,16,4,76,2,193,160,93,160,166,43,85,82,104,14,249,172,98,114,145,151,196,187,55,226,74,44,136,83,134,176,173,55,112,239,16,53,2,64,227,240,88,48,155,3,83,97,8,79,10,35,110,243,97,3,161,214,5,26,32,229,194,18,151,200,155,13,163,132,31,136,113,8,240,200,224,0,152,66,16,241,64,240,138,17,66,204,213,28,228,123,96,123,1,250,90,144,11,110,128,224,185,110,184,29,77,101,194,104,162,27,48,185,9,59,66,120,221,67,0,52,242,54,190,141,65,246,133,57,4,139,134,131,56,132,108,63,26,5,134,176,63,209,250,44,8,13,75,202,187,16,151,144,36,137,58,97,110,170,164,6,40,152,15,153,195,4,71,251,209,37,5,245,212,200,236,64,188,142,16,150,79,134,95,5,133,203,63,154,55,237,231,248,44,206,77,248,186,97,218,224,23,42,0,197,148,129,22,100,33,174,143,131,180,114,37,179,17,188,4,138,153,64,12,170,103,32,234,192,2,207,27,113,177,36,98,0,172,34,112,94,36,81,48,146,100,193,48,222,231,72,64,85,7,231,43,200,20,159,193,46,42,177,53,141,203,25,184,184,26,16,72,31,19,87,153,49,55,115,182,113,198,145,235,106,227,98,237,176,198,101,64,149,24,39,226,182,188,195,10,80,51,196,214,102,149,5,9,194,170,245,96,23,194,73,102,66,3,114,133,74,8,147,74,56,8,196,73,241,10,77,140,64,200,31,69,21,112,136,216,63,139,88,166,23,228,98,227,98,103,73,130,86,57,172,210,180,89,181,194,201,102,149,21,168,213,66,26,92,188,6,144,16,161,120,13,100,134,245,241,115,253,26,84,219,162,187,133,116,152,142,248,106,28,22,147,1,178,206,1,53,81,97,212,43,28,72,46,132,156,88,144,233,203,244,194,82,80,1,253,73,36,46,33,94,138,70,27,57,28,30,56,74,133,179,52,155,198,1,146,29,203,59,196,106,35,1,161,142,237,179,130,104,44,113,163,245,103,103,22,165,61,67,45,200,78,140,82,228,37,59,26,86,33,4,92,49,198,96,66,176,31,56,2,197,160,98,125,128,91,135,189,17,233,229,3,51,217,129,132,80,11,190,147,197,101,178,185,196,144,1,3,246,166,211,188,97,6,5,214,32,137,119,187,73,3,66,185,226,200,207,223,210,187,58,158,163,75,133,233,52,79,96,208,1,224,188,217,76,14,71,188,111,129,15,201,133,200,20,46,7,236,142,255,154,63,80,233,57,64,125,48,217,144,39,190,100,116,26,126,231,157,27,118,0,142,74,246,37,123,15,140,225,35,111,227,41,1,146,228,0,144,6,46,9,178,209,24,20,26,21,49,108,209,173,4,196,128,65,99,186,52,50,29,239,20,151,208,20,31,50,130,34,152,13,145,217,232,158,57,162,197,197,186,26,28,140,24,228,232,2,108,242,196,50,134,135,62,161,49,8,229,94,6,38,42,160,34,224,183,123,226,56,84,94,224,96,7,74,176,222,76,38,213,159,70,39,198,14,183,66,28,46,147,197,2,53,53,41,232,157,154,108,200,139,76,163,243,216,168,54,34,211,241,212,94,52,137,131,241,235,76,16,144,63,207,166,12,192,7,58,48,204,209,32,1,58,68,12,244,193,129,56,172,15,113,48,157,76,245,163,129,77,82,44,111,30,156,6,65,145,128,39,55,96,221,163,28,96,164,5,153,129,251,12,17,44,224,146,23,25,217,76,162,168,9,76,225,10,174,168,28,200,174,131,55,11,127,187,221,134,91,161,20,31,38,19,141,130,130,72,231,128,205,118,16,115,133,200,144,23,12,228,9,9,187,113,145,140,21,19,194,142,92,146,112,233,23,8,232,14,246,101,208,184,98,126,20,239,222,210,113,216,33,166,39,29,139,66,113,240,106,107,88,9,62,241,121,3,46,238,95,209,56,3,182,123,96,45,200,154,233,143,120,66,168,43,41,70,24,192,39,161,99,201,252,64,70,11,131,78,216,13,17,219,220,216,182,8,8,226,98,143,17,65,42,17,163,0,94,96,233,72,118,81,36,18,93,18,41,34,144,1,22,19,70,124,38,154,23,42,159,17,134,71,249,29,224,198,75,140,27,42,236,5,51,168,36,44,107,157,78,253,69,232,156,204,246,5,146,8,55,174,197,88,148,176,51,143,205,150,236,150,97,145,99,50,135,3,46,87,196,131,168,164,159,227,198,158,129,152,177,33,153,16,122,48,81,140,83,177,49,239,79,160,70,130,217,40,134,5,37,96,203,85,104,49,173,95,164,193,129,223,205,28,29,45,87,89,216,172,51,70,150,16,68,11,88,44,122,32,150,190,64,76,221,3,247,212,35,160,248,139,247,146,32,8,114,249,135,47,144,240,35,81,3,162,9,184,89,205,164,209,97,54,139,142,72,107,188,122,160,216,147,199,202,62,193,12,10,157,201,65,133,190,39,155,76,217,10,115,57,144,234,6,119,85,137,147,66,39,83,112,109,23,136,19,19,144,170,152,215,71,240,164,181,32,117,11,38,99,174,56,95,128,192,163,120,231,51,53,32,224,173,163,85,149,197,37,96,197,112,224,197,24,37,106,155,176,55,11,78,250,160,245,167,240,141,80,224,212,227,87,234,186,194,16,153,206,97,130,83,102,72,107,44,78,138,75,113,208,22,165,27,14,90,75,24,187,29,97,192,113,17,124,107,21,28,193,192,82,86,152,12,130,20,231,32,47,170,130,155,93,97,42,132,200,96,85,172,234,215,207,201,47,160,6,26,153,67,19,239,199,99,152,195,247,93,197,225,25,73,144,131,204,166,248,208,252,112,73,41,217,76,220,16,24,24,24,232,14,109,192,139,44,14,218,101,117,7,205,49,34,161,18,124,166,129,228,67,34,38,132,66,234,72,3,113,206,165,6,40,176,143,251,35,136,32,64,213,23,22,62,199,205,120,26,3,115,67,129,104,20,83,148,216,196,33,120,253,226,91,57,137,33,59,156,144,201,92,156,220,255,46,229,20,203,122,214,212,209,90,0,94,249,39,22,250,95,217,30,88,206,153,2,49,74,57,0,95,56,120,52,206,128,6,127,101,129,255,15,205,111,220,240,6,104,115,134,225,1,32,224,68,46,174,102,73,39,51,188,121,104,165,53,63,152,205,24,156,217,135,69,75,36,246,58,231,231,121,253,247,48,199,255,3,159,191,204,255,183,39,111,133,17,94,252,95,24,227,111,206,127,44,212,209,253,41,255,95,111,225,127,235,127,252,71,62,22,54,78,38,44,79,109,111,166,2,90,27,212,210,195,202,193,193,202,206,210,195,209,220,195,209,204,197,218,68,155,199,97,107,131,195,116,218,184,174,37,211,233,198,144,194,112,182,47,164,201,246,130,102,171,91,216,56,105,40,12,247,221,74,165,177,33,77,150,248,1,74,74,144,166,205,108,245,95,247,173,1,105,218,104,109,84,24,62,92,83,211,155,233,193,228,113,77,88,100,174,15,199,4,187,2,129,13,211,129,137,109,172,165,141,118,9,33,109,181,0,157,106,147,89,52,109,66,118,35,90,55,113,112,3,68,216,99,191,252,91,224,252,106,96,228,159,159,71,3,15,192,87,15,252,146,131,159,218,112,252,201,222,222,48,27,255,255,207,13,252,200,116,26,149,204,133,197,95,196,176,251,250,97,88,69,135,7,103,229,36,224,72,152,22,172,36,250,195,60,226,27,131,22,139,208,139,194,112,10,21,194,231,9,158,67,106,106,144,55,19,242,101,34,38,18,141,11,253,126,196,95,191,200,165,81,3,145,63,41,84,72,83,65,65,203,209,218,97,149,155,49,56,168,137,30,134,86,80,64,190,27,43,32,51,135,57,92,79,30,141,78,213,226,248,40,40,128,95,141,7,211,214,255,223,76,242,127,248,243,151,242,223,201,210,204,194,222,242,127,88,249,9,253,252,141,252,215,55,48,88,52,88,254,47,210,253,239,249,175,255,200,103,22,40,235,4,105,66,144,25,4,170,198,106,226,150,31,9,98,209,121,222,154,52,6,9,242,161,121,251,104,98,41,116,192,20,71,184,221,139,77,246,133,65,46,189,194,172,89,144,43,150,214,137,244,166,160,0,250,4,183,128,252,244,42,242,11,86,254,31,120,89,226,110,176,100,39,144,207,203,161,121,131,195,83,120,62,60,22,103,7,78,1,226,56,161,128,117,86,68,129,140,106,63,152,77,166,211,177,215,48,231,148,51,120,219,155,77,99,80,104,44,58,12,206,52,91,146,57,120,208,204,24,242,228,113,208,218,12,226,91,9,136,55,134,128,163,238,146,67,18,12,26,140,94,39,47,222,161,32,78,102,0,192,226,153,105,129,210,2,92,152,61,32,19,214,24,178,16,111,39,130,43,18,176,234,244,136,39,36,217,104,196,171,66,14,74,162,13,100,193,28,18,40,155,67,197,211,113,169,136,43,10,140,125,164,133,47,204,245,97,82,57,24,138,36,72,198,144,132,229,239,162,135,248,177,68,103,241,156,241,160,168,164,72,13,237,39,232,197,222,24,40,10,1,160,71,166,105,5,118,225,233,144,26,100,77,243,246,129,28,37,11,111,140,22,207,21,3,66,24,78,226,80,129,43,124,60,217,76,50,21,115,157,153,94,248,207,40,140,20,152,65,102,211,152,28,132,88,232,48,196,33,83,216,136,187,130,166,75,115,65,189,8,6,68,36,55,127,31,52,163,155,69,102,227,87,4,137,125,156,95,247,60,96,217,28,233,60,111,26,3,133,29,113,167,217,191,158,2,157,28,8,179,177,66,9,64,156,146,209,36,119,50,5,43,66,3,106,119,97,245,199,64,228,65,188,101,135,248,224,92,152,130,252,66,92,28,49,144,3,87,73,11,178,65,79,138,32,170,20,117,249,41,62,16,133,201,134,177,154,10,224,82,3,63,180,142,20,131,10,179,96,6,21,100,22,163,233,243,20,50,11,13,46,209,64,65,22,58,25,63,31,133,209,50,234,236,1,196,137,35,241,12,178,47,141,225,173,141,30,134,210,246,133,185,108,26,133,163,77,103,122,123,35,143,185,108,50,130,125,109,50,143,235,131,22,67,209,32,65,150,1,92,152,1,200,144,197,164,49,184,28,2,166,36,121,101,76,136,12,170,107,33,204,236,141,93,197,138,210,147,24,81,8,34,36,149,224,240,10,234,3,49,194,89,12,228,207,10,236,29,5,77,124,103,28,164,48,138,253,88,78,103,69,34,154,187,65,36,98,98,57,119,10,157,134,111,133,0,79,24,16,245,128,83,57,226,155,160,108,44,236,72,226,134,32,82,200,224,66,76,22,44,190,144,4,63,219,129,133,114,9,96,136,139,144,80,230,207,71,108,181,45,100,63,178,22,168,178,128,214,217,67,101,48,174,133,17,168,205,6,61,195,33,35,36,210,227,98,9,156,13,34,115,64,138,3,106,83,13,184,34,78,124,50,10,59,95,73,248,65,188,218,136,201,172,237,205,102,81,52,8,105,184,248,5,84,226,246,0,98,46,27,38,251,34,242,220,24,178,97,136,35,152,232,193,14,48,25,100,209,120,224,246,17,68,95,80,200,116,58,9,213,54,32,116,38,198,13,7,116,132,52,150,52,67,117,1,86,157,14,171,208,129,69,235,126,193,178,76,47,136,14,98,234,224,186,26,144,47,140,69,42,72,56,190,141,177,22,32,188,196,99,209,153,100,170,54,149,233,207,64,190,144,112,33,203,226,113,124,72,16,194,123,48,197,7,196,246,188,209,115,37,218,8,205,50,209,16,7,190,105,47,169,158,229,132,192,138,233,36,8,166,48,233,76,239,64,99,116,166,226,157,86,236,103,194,129,12,32,83,65,177,46,68,242,1,113,234,11,162,202,0,173,48,133,137,31,225,16,175,13,178,44,120,255,218,104,125,15,196,241,64,68,61,15,230,104,35,4,200,5,117,253,185,236,64,49,47,138,181,234,32,245,133,107,61,44,39,18,219,174,0,201,201,76,127,198,175,36,2,54,50,88,123,10,153,142,69,169,141,33,115,162,210,195,209,128,137,50,60,253,12,151,153,36,52,68,139,107,92,10,153,33,78,8,192,223,244,34,83,64,142,47,154,159,138,232,29,152,197,5,215,7,208,193,214,19,147,141,8,120,14,147,65,166,3,25,203,129,41,76,6,21,161,50,162,38,70,196,96,0,75,124,85,141,88,102,15,144,128,64,92,195,48,87,2,16,3,134,169,28,2,209,176,200,200,155,200,184,152,79,134,110,77,243,184,62,136,54,192,47,19,98,195,160,48,10,26,195,198,80,175,160,9,173,64,196,27,126,100,7,48,147,31,204,70,8,14,48,18,154,55,15,120,135,201,166,162,201,240,44,54,186,31,139,97,31,203,219,244,132,209,45,60,14,216,42,192,59,129,169,16,149,135,149,47,164,82,17,33,198,38,123,33,26,131,195,99,99,187,107,152,164,192,118,235,56,24,247,137,229,39,7,242,250,7,16,74,72,23,89,86,177,97,242,107,78,4,87,234,128,82,78,56,1,97,71,59,1,173,160,162,26,19,117,48,85,34,21,21,20,52,161,13,203,231,207,119,87,215,64,190,89,49,177,47,43,201,126,100,228,43,242,154,11,19,66,76,117,46,126,77,27,48,52,29,97,182,216,96,69,235,73,161,109,64,93,50,236,170,34,30,122,46,146,131,95,24,232,197,228,49,240,240,191,194,134,129,215,20,113,240,227,221,88,45,0,196,247,165,49,33,127,216,147,67,227,194,238,234,248,5,86,4,167,152,202,164,112,180,53,180,160,229,76,42,172,128,29,38,69,47,40,145,156,106,197,246,26,240,95,209,77,100,38,59,80,139,48,113,99,104,3,152,128,38,152,129,187,186,6,164,13,109,224,113,96,182,38,152,12,246,0,239,130,136,169,127,235,77,12,181,255,250,187,3,214,2,99,57,201,130,12,200,38,1,88,192,202,24,205,84,80,32,214,121,219,128,237,86,137,211,250,97,119,245,65,37,135,53,48,217,229,79,163,211,177,106,169,160,20,18,90,67,65,129,43,49,201,16,206,6,164,204,244,194,43,50,2,245,135,42,114,226,145,111,188,94,35,15,175,245,0,142,216,145,25,84,5,159,193,240,224,133,188,196,135,117,16,222,65,122,65,236,1,180,138,147,11,27,220,78,193,241,97,50,193,70,177,130,51,34,140,105,190,64,89,129,210,131,222,76,200,159,205,100,120,139,139,220,81,124,96,202,86,8,187,77,87,97,195,160,30,32,12,233,46,78,224,218,115,103,107,7,7,49,50,104,96,39,17,160,20,14,96,193,108,26,204,160,72,74,167,162,105,122,8,140,40,104,120,189,14,133,65,123,122,132,61,25,224,255,253,141,255,255,63,172,252,131,126,254,198,255,215,211,215,89,56,184,254,207,130,133,11,255,235,255,255,39,62,18,255,95,144,153,216,154,159,219,154,19,212,18,20,44,140,61,204,47,47,18,68,29,109,9,10,110,59,123,76,24,148,221,186,183,82,148,24,202,102,81,4,21,65,130,216,67,194,19,251,132,169,69,128,210,144,247,133,199,242,249,229,65,252,210,112,212,245,23,30,203,23,164,149,241,203,98,196,253,136,14,238,19,84,23,182,230,85,181,230,157,16,37,134,242,75,130,132,231,170,196,61,59,57,46,39,118,219,89,17,37,140,191,196,175,60,130,182,111,11,46,20,84,157,225,151,103,241,75,34,5,49,105,130,240,227,136,11,207,175,172,22,197,229,136,242,130,4,209,241,157,21,137,252,146,68,193,129,19,104,47,216,216,160,175,214,234,164,214,19,81,194,228,104,201,175,101,113,173,249,89,232,139,194,163,165,252,170,106,164,183,178,195,109,65,137,160,159,104,193,193,40,81,98,40,246,74,108,126,235,222,74,116,44,201,79,69,225,194,224,252,182,160,68,126,245,9,209,249,114,65,106,100,75,80,176,168,226,104,107,246,73,81,122,176,224,112,84,107,246,73,65,76,164,168,226,180,240,104,169,160,34,22,153,15,10,12,152,143,224,112,148,32,47,85,20,83,192,47,57,128,0,179,183,18,105,191,239,34,191,36,166,181,250,56,191,44,9,29,26,65,19,6,85,146,130,38,212,22,148,8,96,136,19,99,173,179,34,17,237,22,157,81,91,80,8,210,160,44,70,84,158,34,200,204,22,100,38,10,227,11,4,101,113,162,184,28,65,114,153,240,120,126,103,69,148,40,169,68,152,31,215,118,56,92,144,95,42,138,40,21,228,37,18,27,32,83,19,47,0,218,115,236,25,126,69,162,40,162,76,20,113,129,95,18,36,10,41,197,135,70,64,18,175,46,2,73,252,37,126,201,25,236,173,228,28,97,106,145,48,53,84,50,223,176,98,126,229,145,1,179,206,207,18,70,69,136,34,64,135,96,141,4,225,251,4,231,67,4,135,163,132,57,39,4,41,9,160,219,40,193,193,80,164,219,244,18,65,245,94,244,185,48,57,72,144,85,217,186,183,82,144,153,38,138,60,39,58,27,41,172,136,107,173,78,66,26,231,151,34,235,14,176,39,188,80,46,58,184,79,148,84,34,8,187,40,74,12,69,218,31,72,234,172,8,23,230,199,9,78,133,252,115,159,86,148,27,209,89,17,129,116,142,194,28,123,144,95,149,36,140,56,45,56,31,47,10,41,237,172,136,226,151,103,9,194,130,91,243,74,132,177,135,5,97,89,232,10,162,243,66,230,2,218,183,149,31,107,205,203,68,167,143,160,14,97,27,81,68,169,40,164,84,65,19,106,45,206,65,249,174,179,34,81,144,151,33,12,47,22,157,205,231,151,96,243,16,157,197,8,13,37,106,162,11,10,214,51,79,16,17,45,168,8,18,150,29,20,69,132,11,147,207,9,227,242,133,81,193,4,231,82,148,27,129,119,143,172,153,32,51,17,235,47,58,182,53,47,15,89,57,192,3,130,234,179,109,65,105,194,212,80,65,121,153,40,49,84,144,153,136,54,64,161,232,172,136,130,208,191,5,81,97,194,200,115,40,49,162,79,196,30,35,134,140,216,3,130,131,161,162,236,232,214,253,103,4,121,137,252,210,8,124,36,64,50,133,193,130,138,88,208,56,17,106,59,158,201,47,219,135,66,204,47,9,18,148,197,33,52,150,27,135,10,154,214,130,189,162,184,28,148,131,4,153,8,49,32,162,165,181,250,24,250,130,184,39,180,29,66,178,73,151,4,89,149,130,228,2,148,157,4,153,217,194,163,251,249,229,69,252,146,3,252,138,116,109,126,73,100,107,101,37,34,220,0,251,34,190,94,75,80,48,153,38,58,95,222,154,159,219,150,118,177,53,127,159,32,252,172,118,107,246,190,182,140,67,162,131,251,16,118,206,141,64,186,137,47,16,70,231,241,43,210,91,171,142,32,184,25,192,83,200,172,248,37,5,130,252,40,148,29,68,113,105,194,160,224,206,138,68,32,8,193,242,243,203,246,241,75,98,248,37,137,162,248,40,126,73,185,176,48,24,109,132,178,55,194,117,224,77,49,117,34,200,68,91,252,157,151,39,166,78,116,17,81,33,216,22,20,33,140,60,221,22,20,34,56,24,142,44,66,241,121,177,56,195,184,2,3,17,208,67,108,62,74,205,194,160,108,132,0,9,162,83,34,188,19,49,78,70,86,24,149,179,177,249,136,60,6,98,17,107,86,156,37,136,1,220,27,121,74,24,126,70,112,60,7,245,215,80,222,70,120,56,40,27,237,138,95,22,37,60,135,201,98,97,74,22,54,58,42,31,49,46,141,18,150,159,104,45,186,136,77,39,57,72,120,62,4,121,8,144,211,89,145,136,144,65,126,177,240,124,136,32,54,4,89,155,244,19,109,103,162,16,77,21,113,73,152,178,183,37,40,24,251,181,50,94,16,94,4,80,132,145,158,48,6,225,201,214,234,253,173,149,149,252,234,20,225,129,76,32,241,203,248,101,251,218,142,93,16,230,102,96,179,75,74,231,151,148,181,230,85,183,37,228,181,237,143,21,157,9,22,100,164,10,195,143,98,42,225,120,142,48,62,172,45,49,185,45,40,93,24,126,16,67,44,208,87,162,196,80,81,105,176,160,250,184,48,252,104,107,80,24,54,80,73,180,32,54,31,37,81,132,38,48,41,136,208,4,162,79,136,212,196,47,137,68,150,170,48,184,109,127,44,2,107,120,209,32,112,113,66,137,226,87,167,180,230,7,139,21,5,58,0,88,66,84,186,160,60,130,50,254,63,113,174,4,167,66,248,149,241,232,130,162,134,60,186,196,130,228,156,255,45,15,73,24,81,37,8,47,16,230,199,242,75,206,160,128,33,128,3,177,35,8,203,106,75,200,65,148,104,92,142,48,188,88,24,181,95,16,157,32,56,28,197,47,71,20,170,40,179,140,95,21,137,176,98,238,41,126,105,122,107,97,168,240,232,241,255,87,61,39,12,209,37,101,128,20,130,19,91,47,157,16,69,229,41,40,180,165,164,10,74,74,132,231,50,90,171,99,16,237,157,87,36,42,63,62,160,205,76,5,5,65,121,25,34,146,67,114,4,201,57,88,23,232,111,252,210,72,65,68,52,9,18,132,133,183,29,11,107,205,47,231,151,4,241,75,34,255,137,147,69,130,4,121,123,249,21,137,8,210,243,43,248,149,233,252,50,68,242,97,253,162,11,144,24,138,169,247,194,96,81,78,36,9,66,57,209,24,155,140,48,246,32,139,173,141,125,7,10,4,125,13,123,212,90,125,16,209,238,209,241,130,176,189,194,194,200,214,252,120,81,110,4,26,9,104,11,222,47,8,47,64,184,44,227,152,48,40,134,95,26,46,56,144,170,160,32,56,21,34,76,77,150,16,99,107,245,126,81,78,36,177,49,9,194,200,51,44,92,148,28,41,74,142,252,23,28,41,124,194,130,67,7,90,243,35,144,9,139,7,66,135,64,213,23,58,16,80,133,161,162,131,251,80,61,244,139,169,3,247,75,27,193,119,89,146,160,164,164,53,59,24,125,19,107,16,115,88,152,150,37,158,240,63,245,202,254,115,159,191,244,255,92,29,156,108,157,29,205,150,255,47,84,0,253,187,250,175,6,11,23,252,180,255,171,243,223,250,175,255,145,15,168,179,197,34,83,96,117,252,94,81,144,196,130,147,129,170,134,130,2,157,73,166,170,171,154,122,146,183,195,116,15,46,147,73,231,104,107,163,255,3,65,22,15,42,236,197,209,102,195,44,166,49,200,183,241,220,78,87,37,65,170,200,119,15,44,195,20,233,133,248,183,186,2,126,234,11,187,253,212,3,189,253,212,67,124,251,41,154,203,205,241,33,235,232,233,35,109,168,11,188,244,188,244,23,232,81,23,80,245,245,244,23,44,48,160,192,250,20,67,79,61,178,161,14,213,107,209,130,69,6,240,66,170,161,23,108,232,185,80,103,33,76,213,213,129,245,22,233,123,233,233,27,81,97,202,66,253,133,11,23,225,29,114,217,52,22,225,210,83,124,60,205,69,90,11,117,181,22,96,173,120,108,58,7,50,129,54,136,79,159,170,226,74,205,155,198,245,225,121,14,184,172,30,191,171,94,124,249,43,54,71,109,63,180,79,45,46,153,173,229,189,29,235,218,157,164,32,193,232,47,38,174,173,109,140,127,245,160,194,44,14,142,205,1,15,17,116,14,120,160,254,239,167,200,252,37,255,3,165,77,3,39,41,6,254,162,197,98,120,255,107,99,252,150,255,245,245,23,26,232,233,12,138,255,44,210,95,240,223,248,207,127,228,19,225,184,202,106,164,194,100,132,126,70,218,88,91,56,73,73,13,13,149,146,26,114,85,126,168,148,148,212,234,137,101,242,82,82,35,76,104,203,151,59,218,44,95,14,57,178,153,104,74,168,117,68,188,235,176,117,206,183,149,83,55,28,62,104,106,62,220,194,116,101,171,189,82,155,229,74,121,205,144,32,151,43,43,172,101,66,199,82,160,156,231,15,44,229,158,133,28,144,127,126,127,205,24,203,103,50,183,50,84,61,253,199,20,60,187,17,114,224,130,150,114,251,157,164,241,247,97,143,238,230,238,42,142,168,218,187,166,79,244,103,233,162,174,102,105,211,202,227,243,149,189,79,76,150,162,70,178,231,60,152,41,253,103,68,132,141,221,67,231,32,169,169,7,131,71,93,46,169,152,186,112,254,188,121,83,77,39,209,251,181,58,243,150,51,213,93,219,225,141,253,237,253,249,25,183,85,248,239,165,76,51,160,85,175,68,239,47,204,92,58,66,106,211,237,113,182,108,105,232,78,187,215,34,206,13,157,17,19,124,108,55,135,40,105,31,121,165,43,151,23,247,106,188,220,82,168,43,34,218,107,121,163,66,208,129,201,9,243,109,134,4,61,29,245,238,207,37,155,38,243,211,191,152,181,171,191,86,180,148,202,89,52,243,235,189,154,212,154,253,134,147,60,183,182,206,218,183,238,102,231,161,143,67,28,234,95,24,58,239,51,44,109,188,52,243,220,177,200,141,46,50,97,70,175,73,29,237,253,23,167,246,111,184,112,49,115,239,66,210,137,51,89,182,230,39,97,206,62,94,249,113,35,19,187,125,79,160,142,9,89,22,22,230,231,228,62,12,155,233,209,49,122,225,74,155,132,125,55,53,250,86,15,217,52,106,202,211,17,11,32,63,62,103,200,53,72,63,200,112,93,220,132,49,121,151,178,51,21,246,26,41,93,155,16,82,51,86,200,246,156,249,52,44,224,56,52,87,125,69,219,197,53,58,38,235,39,41,230,218,198,23,184,173,236,53,202,179,152,238,170,252,182,74,119,81,76,22,127,79,138,214,75,245,238,133,235,119,111,167,203,92,31,31,126,239,83,232,135,49,74,143,32,191,91,183,163,134,59,247,68,221,115,240,182,26,209,99,157,249,224,66,223,189,153,49,202,225,230,50,227,251,214,109,58,51,219,112,125,155,71,92,202,34,67,15,250,214,178,131,227,78,92,31,198,121,68,89,62,225,203,149,245,129,27,3,127,176,180,214,149,155,94,63,48,133,63,134,111,55,98,70,178,162,135,210,196,204,99,139,191,218,65,7,34,87,127,220,169,36,26,106,49,255,230,235,241,219,214,198,61,156,97,48,129,26,118,171,253,148,82,57,159,127,67,253,143,215,31,74,89,102,243,190,125,112,217,198,112,57,167,234,176,100,217,222,197,90,43,15,141,174,154,28,58,68,95,94,214,14,10,75,148,57,181,119,4,68,127,155,219,25,230,127,32,117,243,101,185,177,7,135,202,94,222,68,155,52,245,16,212,57,230,202,214,17,183,134,237,49,159,45,101,180,188,69,134,95,41,115,112,216,59,143,253,231,14,156,53,177,142,239,18,222,182,162,134,204,85,242,222,187,224,160,92,103,214,199,213,25,39,124,62,188,92,120,73,190,127,76,138,98,252,176,79,247,66,230,189,237,239,250,106,246,214,95,81,113,253,213,120,229,182,205,22,167,122,210,231,46,12,159,104,61,98,206,208,113,190,172,93,141,42,93,55,175,189,122,50,227,204,184,142,224,29,163,106,90,202,151,189,26,126,98,239,251,131,172,232,251,150,37,122,246,235,160,73,71,5,1,247,229,186,247,198,23,90,119,159,87,46,153,195,231,222,24,194,154,113,107,212,241,109,67,243,70,183,111,83,153,184,63,172,247,202,173,188,251,119,214,10,53,207,42,112,38,118,189,240,122,127,237,145,99,207,161,105,183,213,3,101,235,210,232,38,59,103,223,59,42,52,190,174,122,246,75,236,151,213,252,68,29,23,230,87,199,218,247,223,218,103,156,169,221,239,251,156,229,64,159,228,39,191,56,50,229,122,13,197,126,157,201,102,207,185,5,67,219,199,250,217,237,219,191,246,25,165,251,205,228,40,101,205,218,185,227,62,202,247,143,97,190,191,125,103,222,241,150,117,45,207,91,190,89,62,72,152,127,108,206,14,171,33,95,185,31,232,17,11,52,77,18,110,135,120,200,74,31,153,245,218,40,202,211,216,200,216,104,8,212,91,165,190,201,131,57,241,99,231,208,171,37,239,155,214,22,76,147,154,241,34,56,56,248,84,103,81,1,67,106,212,21,127,125,65,179,127,146,94,227,163,75,171,164,106,114,91,108,230,4,42,76,209,42,87,122,185,193,124,90,135,174,201,102,217,63,131,244,146,99,199,177,134,52,95,158,33,27,188,13,26,123,61,196,98,193,4,175,180,81,207,74,101,255,148,229,92,81,117,148,63,112,101,75,193,244,184,189,154,155,23,63,31,249,53,120,111,250,116,221,224,35,47,71,148,200,215,95,209,99,13,203,75,101,188,151,249,28,236,255,114,81,8,52,59,244,192,253,49,38,215,39,158,55,109,87,154,123,125,200,7,203,144,131,172,217,147,109,44,14,31,210,181,8,181,62,84,122,203,51,115,162,134,217,157,67,190,214,122,31,231,179,199,27,69,36,91,25,31,220,112,107,72,230,176,192,232,157,230,11,93,70,62,89,49,114,181,45,87,247,77,240,133,251,11,116,149,83,66,78,157,88,116,127,39,119,120,217,88,205,229,103,239,87,250,76,219,62,182,50,124,211,242,242,251,42,62,203,134,46,88,19,21,124,124,243,215,99,195,110,222,84,61,63,155,52,225,200,230,79,231,85,207,141,63,123,117,203,249,21,223,146,243,55,187,175,211,254,58,102,238,107,110,114,68,195,181,9,83,15,252,241,106,201,206,161,75,103,120,4,39,180,148,127,48,174,152,80,29,178,236,114,239,123,166,236,188,43,65,155,173,222,171,178,228,199,13,167,133,30,15,53,55,215,32,207,125,37,255,74,183,209,182,41,212,223,66,245,144,217,37,213,178,107,149,199,172,255,132,106,102,230,65,12,213,142,185,250,227,22,135,199,134,127,159,61,214,38,150,106,245,113,166,229,225,146,204,141,78,51,105,179,104,218,109,178,167,143,60,182,239,73,207,56,227,121,238,117,230,216,115,135,51,85,157,52,28,53,214,212,157,100,111,204,114,22,156,190,227,125,97,104,93,72,187,101,204,236,79,183,47,222,62,123,107,241,173,104,254,93,62,227,163,247,1,181,27,7,94,47,143,200,162,58,42,175,190,163,94,24,247,40,174,60,206,224,204,153,51,167,206,164,158,25,231,18,118,70,113,205,93,151,209,57,169,206,187,210,123,86,219,219,222,91,27,157,171,239,102,127,166,200,201,55,97,253,197,122,205,66,3,151,121,79,14,191,113,176,207,16,58,185,58,157,61,157,157,211,117,122,134,15,55,113,72,244,242,150,71,202,247,231,249,240,46,173,170,183,229,93,40,11,51,182,221,117,102,123,213,246,211,61,51,191,220,125,83,57,153,58,210,118,100,209,80,87,74,213,138,176,155,171,163,167,76,254,158,200,189,183,48,241,80,98,93,226,124,221,46,159,212,103,59,79,89,62,188,240,88,225,225,235,173,154,15,234,243,120,43,223,142,153,118,50,233,65,29,119,250,174,133,187,134,125,215,173,220,144,148,227,155,117,239,65,205,125,173,167,205,217,77,167,154,178,79,102,181,100,140,203,95,100,155,109,46,58,182,74,101,8,101,157,142,97,20,233,230,188,155,102,55,121,55,179,199,236,155,181,110,150,236,172,163,177,57,211,30,24,189,174,236,176,118,223,227,30,204,56,212,177,187,105,107,89,218,231,99,219,205,182,31,223,190,245,243,155,47,29,109,45,61,69,61,227,62,123,191,97,62,93,150,251,98,177,211,142,204,46,235,230,91,25,135,134,89,53,235,155,142,164,143,204,24,41,156,72,55,40,161,222,103,250,80,39,122,170,235,55,250,4,220,41,120,22,78,230,51,227,200,151,106,90,75,86,199,46,108,122,254,108,157,79,69,205,183,208,15,156,83,163,142,220,248,211,243,232,194,13,199,119,169,13,85,59,161,230,116,196,87,205,87,45,205,62,215,174,197,78,209,174,43,169,121,209,201,99,129,199,178,18,115,23,109,93,248,118,145,129,254,12,230,210,103,21,55,251,138,228,234,174,94,83,109,242,220,123,195,45,178,235,232,218,163,195,143,218,106,190,213,76,115,107,91,191,237,220,199,220,45,231,58,214,59,231,126,63,231,189,206,213,205,163,112,102,125,192,115,106,61,253,2,173,216,210,215,221,247,145,239,124,186,118,195,9,63,134,159,121,185,189,223,180,147,242,39,151,88,69,172,88,19,93,70,206,247,170,189,80,123,49,255,252,158,151,151,89,242,254,234,172,28,255,0,163,250,157,220,135,173,122,39,107,99,126,8,91,223,28,19,148,92,251,80,51,49,119,97,203,205,241,81,180,169,159,234,111,63,141,16,185,188,226,62,57,254,102,106,123,197,229,210,43,221,241,145,41,145,151,225,139,119,237,93,203,222,6,60,203,202,211,204,243,104,106,108,154,205,40,100,152,116,8,59,110,119,196,119,24,44,185,100,146,177,100,109,64,242,167,217,1,67,3,180,222,211,63,246,181,10,132,241,111,121,247,223,106,51,119,116,218,117,154,52,215,222,92,31,61,33,170,105,225,215,67,177,167,71,63,243,78,114,72,208,126,100,80,231,127,150,153,144,22,49,227,89,254,157,206,19,213,199,151,189,216,147,221,239,124,116,228,252,189,133,9,95,116,46,47,52,29,203,154,253,210,164,33,210,36,182,105,106,184,220,62,89,101,185,34,57,154,220,13,185,248,97,77,163,245,71,174,82,204,27,222,161,184,109,228,241,113,15,167,174,148,31,169,232,62,110,251,94,202,173,87,219,206,24,237,106,105,252,227,222,148,103,147,79,41,43,143,91,59,253,235,130,70,253,141,99,155,13,167,79,91,198,232,171,255,224,63,139,164,106,49,230,203,33,232,240,184,82,253,143,155,226,214,60,142,202,121,161,166,52,215,194,62,231,216,251,217,219,237,62,55,182,94,92,248,249,24,109,225,14,207,230,27,67,175,231,29,168,28,231,61,109,110,244,214,8,215,216,180,169,30,211,250,151,206,92,112,98,246,137,173,175,91,35,62,169,109,178,123,236,48,94,77,127,246,161,195,175,143,248,169,125,113,80,72,188,180,219,169,139,250,236,118,216,145,124,135,243,137,58,91,239,116,159,238,113,190,120,106,122,210,169,165,209,139,223,57,234,204,52,154,25,232,240,81,133,49,187,248,64,67,218,85,155,211,118,109,45,231,3,167,4,104,127,251,209,199,235,155,30,28,155,110,241,94,247,201,220,194,217,95,220,18,29,234,235,47,165,114,171,63,63,252,188,105,230,134,117,90,59,227,199,36,158,159,211,178,203,139,42,204,251,51,248,92,232,185,239,117,243,234,110,215,89,89,174,207,176,91,253,150,123,178,237,226,41,255,240,119,215,195,94,231,77,218,180,232,105,109,235,145,80,27,63,33,100,228,204,158,204,46,124,21,219,55,231,116,225,231,185,109,123,151,188,168,56,80,49,122,81,139,247,244,196,44,35,91,221,183,15,233,13,117,119,189,151,221,27,93,211,15,143,90,186,223,32,27,206,187,221,104,201,153,241,39,229,94,131,254,140,227,105,58,213,112,112,93,200,28,197,50,149,125,164,198,202,240,11,234,156,7,157,114,49,114,115,228,152,42,115,73,140,141,158,37,212,87,135,173,150,133,245,185,56,91,207,143,27,223,188,238,77,37,247,174,206,206,227,44,183,6,182,72,48,37,97,207,252,215,42,238,234,126,36,45,205,31,23,66,138,95,95,173,165,236,214,234,13,220,12,191,185,83,180,134,113,86,63,95,45,79,57,183,170,234,38,243,94,199,216,123,135,251,14,91,109,253,35,63,119,195,31,27,93,47,117,188,235,161,189,173,77,40,139,99,212,153,214,65,77,247,215,40,111,122,90,240,96,103,203,155,104,143,59,143,238,230,175,145,117,105,207,215,205,217,184,169,123,247,184,61,206,34,175,254,123,133,27,70,20,143,103,118,95,90,83,242,69,88,116,208,151,183,230,232,154,172,134,136,134,79,69,203,234,198,84,183,180,107,79,175,118,233,124,252,194,173,226,211,91,173,7,121,121,77,15,202,55,156,109,58,123,182,107,98,187,219,154,189,79,173,183,110,255,186,170,185,161,74,155,229,177,60,119,215,187,162,239,81,223,111,12,187,44,221,22,44,170,86,235,223,254,125,243,243,43,71,151,79,223,191,101,244,134,169,121,75,204,151,57,185,236,127,124,47,239,237,89,135,252,206,45,214,244,86,67,227,14,31,219,147,254,45,135,94,76,221,221,240,132,250,208,101,155,157,232,249,153,150,184,22,219,152,209,201,183,150,61,120,65,98,116,152,28,247,251,184,250,238,165,163,139,179,213,82,203,234,141,79,20,190,227,62,111,227,120,135,212,38,27,223,53,222,241,58,185,182,244,212,167,77,162,216,77,239,75,28,247,60,120,231,217,52,231,153,173,213,110,255,239,223,173,147,54,108,104,130,187,238,142,124,151,250,46,122,26,101,113,140,127,15,47,181,98,108,128,224,207,53,53,79,34,159,169,230,241,54,198,150,239,254,116,147,63,197,221,160,219,32,173,233,78,217,151,55,126,205,239,106,253,149,155,231,52,106,150,101,111,203,255,92,117,229,251,153,101,244,31,207,95,8,158,242,218,205,94,238,181,29,77,153,222,28,120,125,199,231,215,219,106,90,180,155,108,83,29,211,226,150,234,237,94,255,253,207,54,55,103,7,150,67,239,39,155,218,114,143,112,143,157,29,154,125,206,159,106,239,36,60,213,30,221,47,232,127,150,85,21,177,171,41,127,118,254,208,77,249,1,39,187,188,158,109,72,40,214,252,190,250,123,215,11,184,186,183,175,170,117,111,243,254,166,25,38,75,83,191,199,189,111,107,19,29,247,176,246,184,83,85,191,211,183,79,249,235,187,14,211,175,151,131,142,205,127,117,103,143,220,130,28,159,45,243,164,242,253,165,77,237,101,131,70,213,122,199,217,28,248,148,182,81,233,198,241,53,49,151,247,92,61,176,40,99,99,163,84,78,88,116,187,65,106,211,136,203,210,57,71,29,79,59,194,213,239,207,255,144,226,249,77,127,120,229,98,98,223,70,141,113,170,75,134,209,191,28,58,177,181,172,47,108,243,49,245,154,228,101,124,147,10,57,157,181,42,11,42,190,171,76,125,182,211,228,249,11,215,177,82,82,82,116,120,157,141,151,189,189,212,60,41,41,41,121,41,89,233,201,82,114,82,82,82,210,82,82,82,75,165,167,136,191,175,144,86,151,26,2,190,203,72,73,237,167,73,201,98,207,87,97,46,203,65,236,111,244,255,50,233,50,120,139,161,161,233,67,240,239,67,174,34,77,123,253,71,87,72,73,73,13,103,89,187,113,164,164,148,231,32,255,73,219,56,205,126,47,37,101,42,101,99,97,230,18,32,221,222,52,44,104,194,147,202,111,31,94,84,150,219,14,147,27,111,89,144,30,114,32,196,83,110,71,172,201,83,245,83,17,55,15,168,37,90,156,212,142,88,24,81,213,71,33,173,62,226,227,153,161,182,212,54,228,67,221,142,43,205,231,19,28,199,203,173,118,124,53,179,242,93,223,158,234,69,130,154,166,74,255,210,249,27,58,106,186,99,58,42,57,222,53,127,26,137,56,94,222,95,250,58,140,142,40,114,199,40,203,42,153,74,73,255,213,63,193,127,42,240,23,109,88,52,111,159,148,140,60,20,244,87,255,188,148,149,151,223,54,243,175,127,15,146,146,153,164,2,65,113,31,134,158,218,254,155,110,130,164,164,103,230,253,37,40,200,63,80,139,140,108,168,78,243,101,151,209,191,107,6,65,215,245,126,7,139,60,117,99,80,144,227,205,41,199,222,204,252,93,51,217,208,146,161,191,197,77,148,162,146,210,157,128,33,206,38,191,3,57,40,72,233,217,111,145,119,112,155,180,140,249,36,230,230,51,251,127,215,76,73,233,245,228,223,192,34,45,171,163,101,106,170,222,50,210,238,203,239,64,150,150,49,223,56,228,119,43,96,122,83,78,94,30,174,8,62,61,253,119,32,59,42,74,19,255,254,54,103,65,0,127,226,161,141,171,246,52,86,143,149,125,85,206,151,113,127,22,61,182,53,47,185,234,205,168,226,231,93,183,50,120,38,90,162,81,242,143,234,105,153,155,186,110,122,232,93,228,180,21,93,126,184,110,104,81,107,32,71,43,120,122,203,67,171,8,110,211,210,195,123,102,135,45,123,54,163,122,143,159,85,78,89,111,109,166,232,135,151,191,142,152,58,211,175,41,42,41,189,121,111,111,45,71,152,144,79,170,169,86,62,121,226,187,128,81,186,135,41,210,233,11,130,78,138,10,106,124,34,239,183,70,70,138,74,30,173,247,177,158,181,148,177,95,46,248,92,249,211,77,27,205,187,140,84,110,68,54,6,182,31,83,159,56,254,84,193,103,242,38,191,81,42,118,170,123,68,251,193,160,211,4,63,90,24,251,52,123,216,119,151,59,11,142,238,95,122,176,62,177,162,28,22,126,10,60,157,59,50,51,79,95,91,111,123,108,123,102,103,202,226,39,214,162,178,10,110,155,203,124,247,114,126,214,142,4,227,182,7,133,107,203,252,115,143,164,54,109,201,114,237,50,238,186,184,62,118,213,67,255,194,154,11,235,99,203,148,53,103,205,93,142,209,74,251,240,214,254,216,9,63,92,181,119,60,57,185,130,136,203,251,142,155,223,231,180,92,179,87,62,31,17,98,64,126,174,166,240,177,213,171,120,62,47,93,46,248,227,228,15,231,249,202,205,231,33,7,227,213,121,62,92,219,128,34,22,213,241,77,242,3,155,47,227,95,189,94,218,144,205,218,31,150,74,215,160,111,155,113,210,151,31,11,38,241,142,211,127,252,115,35,47,44,105,181,98,190,166,199,152,161,141,174,143,135,93,240,180,132,190,6,182,177,191,187,21,153,31,37,229,38,220,232,185,104,241,76,69,107,189,214,167,47,222,175,94,191,223,213,124,21,214,241,111,118,234,102,95,97,31,47,223,28,177,115,169,255,113,146,219,5,187,158,188,102,183,167,27,43,207,158,171,92,161,226,118,214,223,117,82,129,151,193,164,231,249,73,35,238,207,80,212,58,143,193,31,244,66,38,74,233,99,249,247,211,38,98,114,8,74,144,81,126,50,220,234,173,221,206,142,237,218,114,57,186,200,12,227,46,31,92,77,201,220,68,121,220,173,238,216,228,82,191,166,206,123,86,40,253,116,238,131,63,27,165,210,18,243,119,26,43,66,187,150,250,159,255,51,241,228,178,139,42,119,237,190,7,10,239,185,125,188,125,206,82,167,229,83,216,133,155,111,220,169,45,188,29,119,148,190,215,121,158,108,214,241,73,153,206,8,109,117,173,57,56,100,12,78,23,195,149,148,222,176,236,87,4,143,145,208,197,58,61,233,41,17,20,231,53,114,198,103,246,203,129,86,113,65,251,66,26,229,239,196,112,210,218,27,53,58,87,200,214,229,164,239,139,140,54,237,225,127,186,241,241,199,31,30,119,50,105,159,4,14,197,213,115,211,118,159,183,216,183,117,179,15,95,121,235,173,91,228,173,37,180,55,147,167,255,225,141,117,123,235,168,148,244,9,122,225,220,66,51,9,75,109,22,200,244,88,114,13,222,109,248,60,53,61,126,134,169,130,172,146,233,101,109,233,174,115,186,149,174,101,109,11,23,57,242,118,104,61,184,188,219,189,169,54,111,214,83,182,222,250,75,212,176,10,61,56,102,73,255,83,149,143,93,59,178,111,49,202,190,135,155,60,123,230,61,126,215,151,213,43,39,165,103,40,96,2,106,125,80,144,227,169,164,132,59,4,1,117,127,221,229,93,109,77,169,143,79,62,186,137,226,95,87,217,58,68,56,169,202,222,239,221,198,89,13,35,221,175,125,39,109,42,51,159,30,192,216,215,215,122,32,129,255,199,139,198,70,123,205,103,235,194,52,241,247,31,200,5,100,108,182,98,154,221,137,37,240,59,71,110,227,176,108,147,229,57,165,195,14,79,151,150,85,122,111,9,29,144,13,27,243,249,79,215,50,219,236,201,70,220,98,158,224,220,131,229,130,254,239,45,185,127,62,75,80,80,69,197,253,89,41,233,153,30,27,82,183,207,146,136,128,249,233,211,146,245,13,195,3,14,86,39,72,233,89,73,5,199,203,95,159,181,119,201,20,155,210,219,61,149,84,97,251,141,249,87,200,6,88,91,174,139,180,140,249,180,66,129,186,1,65,136,120,184,153,206,93,174,58,249,115,252,23,67,37,105,217,37,74,5,73,153,63,206,82,52,76,114,72,107,44,48,108,123,200,202,203,119,63,124,248,120,28,65,4,91,167,223,175,116,91,55,100,24,88,100,200,145,121,34,125,103,250,21,78,127,134,200,168,118,133,229,132,245,41,122,104,211,11,218,166,166,234,189,190,118,35,9,68,162,174,204,218,6,165,232,175,122,19,89,252,105,56,242,240,242,240,18,154,222,16,135,63,134,5,78,148,109,185,96,5,26,94,86,9,94,239,49,111,165,201,24,162,18,26,91,160,93,177,149,153,189,231,197,14,145,2,242,104,222,248,251,233,225,97,123,117,213,248,77,175,41,41,149,91,169,243,162,0,154,114,165,164,103,50,147,82,15,72,208,20,48,127,243,180,100,173,201,22,214,183,26,182,6,29,152,21,100,122,68,134,17,122,176,73,61,34,70,183,237,250,42,108,128,214,117,50,118,147,158,157,175,143,124,168,42,89,253,130,59,50,95,237,162,222,219,118,78,223,253,101,87,252,23,67,105,25,249,111,208,230,139,167,4,50,111,117,62,44,96,117,144,227,119,149,156,58,61,11,109,174,102,106,26,254,150,40,246,107,101,95,103,123,202,26,109,255,190,100,235,246,51,145,82,50,19,20,248,141,151,18,191,48,234,75,20,70,207,156,36,22,235,95,100,100,67,207,84,69,168,67,132,133,209,156,175,212,106,208,236,171,156,185,196,121,102,33,137,228,189,92,42,248,79,249,231,242,51,83,11,143,30,23,102,170,98,13,149,134,43,41,189,118,34,32,233,242,162,96,106,232,65,239,47,167,202,16,42,187,40,123,53,176,37,145,103,173,60,182,161,85,29,151,233,183,78,153,250,234,159,181,204,37,106,168,244,228,160,36,245,188,247,78,90,147,26,16,148,239,145,211,85,59,124,113,117,220,166,152,76,170,241,234,61,218,59,183,196,0,149,201,147,94,33,15,87,134,157,158,65,0,116,142,108,123,239,139,157,195,43,100,71,36,33,157,77,144,111,76,222,214,147,215,255,173,72,182,135,63,91,50,38,194,194,69,243,11,205,9,99,86,4,237,106,115,239,122,216,230,154,26,110,34,15,189,44,14,178,79,242,186,146,190,177,166,58,200,81,75,97,95,247,46,57,199,29,24,25,105,92,142,219,86,71,119,221,18,70,224,32,183,224,130,139,181,25,230,63,120,220,163,150,228,97,8,116,99,229,255,184,229,227,120,235,90,67,230,254,53,171,10,151,156,197,120,122,67,80,144,99,81,67,66,61,145,167,173,161,169,147,248,85,189,205,62,51,166,128,17,250,98,18,22,145,167,86,75,99,175,184,6,5,57,250,53,28,77,36,188,226,232,116,217,100,241,45,19,245,148,206,224,4,89,79,100,193,211,87,31,98,21,25,246,119,28,233,168,29,226,42,54,113,156,130,130,28,213,146,226,87,18,71,187,20,196,219,38,12,96,5,60,178,110,183,68,144,251,89,141,214,162,238,38,102,38,210,112,37,165,59,78,91,157,84,8,70,195,60,37,249,55,122,135,76,204,195,3,131,231,221,87,29,46,35,255,77,125,243,44,141,107,109,122,38,21,171,199,14,251,244,225,112,118,13,232,61,85,94,73,233,99,230,137,211,106,132,21,137,48,109,126,109,246,245,139,255,232,197,198,227,100,215,34,35,124,148,9,110,86,125,183,180,77,164,62,243,135,126,92,181,206,243,189,40,14,255,80,190,223,63,129,106,70,36,217,23,178,50,42,35,50,30,213,22,251,101,87,201,67,142,39,130,154,167,87,78,155,73,245,152,184,25,107,22,108,167,160,164,116,135,122,209,73,131,0,110,162,18,107,215,174,175,149,254,73,139,99,80,193,127,194,180,102,100,198,136,229,230,35,187,224,239,139,60,38,220,218,174,232,188,12,52,77,147,147,151,239,110,236,121,60,77,66,178,182,210,6,238,201,38,208,181,233,179,175,135,160,171,115,249,181,208,136,153,253,132,207,92,126,82,49,100,36,134,89,139,160,32,199,21,147,15,111,33,26,68,167,77,211,175,64,189,95,23,127,72,95,121,195,122,191,148,204,143,225,235,28,45,172,156,182,79,156,50,188,113,134,124,255,250,228,201,168,16,120,185,87,74,122,230,140,245,199,141,9,172,125,112,172,117,143,193,187,211,109,36,240,119,180,156,174,122,198,9,78,228,240,192,226,217,123,102,85,156,53,154,176,2,149,58,189,50,178,161,23,94,220,124,172,68,16,127,170,193,233,205,169,51,50,35,147,244,243,124,84,102,128,199,118,166,67,132,175,82,30,94,123,31,190,223,108,129,214,118,180,237,206,49,16,196,183,181,117,118,32,160,74,53,120,99,115,85,23,35,37,249,115,207,182,213,200,200,2,185,246,85,110,30,187,253,87,116,61,191,148,65,194,129,179,15,174,167,175,141,92,79,180,148,77,141,130,89,167,12,21,135,62,104,115,173,9,127,39,15,189,44,55,13,216,115,41,162,101,231,6,246,78,183,203,197,106,200,130,5,73,201,76,31,190,192,252,214,201,155,167,206,16,204,157,80,153,201,35,30,46,173,153,90,171,244,58,4,1,98,165,194,58,199,217,5,34,249,110,149,209,170,83,93,62,30,216,140,73,176,58,37,8,138,139,246,203,84,38,188,235,66,82,90,170,238,94,190,216,164,189,245,220,196,136,80,121,232,101,169,233,166,189,194,237,71,62,47,100,213,208,51,82,61,122,93,102,0,76,221,149,177,155,148,32,120,154,197,32,188,28,55,182,224,129,217,215,119,254,170,230,89,220,231,136,55,243,124,218,195,232,204,207,219,238,24,166,106,255,161,141,181,170,155,176,57,244,23,252,86,245,126,250,115,197,89,161,43,123,10,198,72,203,42,177,106,31,124,224,102,218,173,106,157,247,218,0,91,134,115,10,239,93,151,158,213,180,173,36,136,50,245,185,47,101,204,140,183,37,103,167,164,8,214,61,71,196,214,120,217,140,240,210,88,231,155,31,198,159,184,10,95,158,140,249,69,227,32,40,238,252,208,44,99,2,172,231,92,76,23,27,190,51,107,187,190,119,237,60,75,25,89,165,247,107,160,233,102,52,3,219,90,229,31,250,1,79,95,186,168,0,106,157,47,45,99,190,73,207,32,222,146,32,116,101,185,58,179,183,247,149,140,71,121,205,239,200,227,61,60,18,220,173,219,46,230,44,227,99,82,210,39,70,61,221,60,94,133,64,69,107,38,168,115,153,202,79,215,126,73,158,138,152,6,84,155,244,102,115,179,110,104,103,243,250,163,243,214,154,185,179,167,199,28,56,19,20,54,27,35,127,115,68,176,36,30,90,73,180,97,71,72,171,12,123,72,107,201,172,154,52,236,208,120,196,140,176,186,108,127,118,82,128,241,210,240,153,153,63,54,182,62,30,15,160,91,28,188,190,115,139,93,24,65,151,190,119,191,124,42,242,81,243,42,175,232,79,223,205,211,127,200,67,142,107,47,167,22,158,234,247,177,187,85,126,227,15,227,29,207,110,185,76,4,175,110,144,150,49,111,214,55,153,96,37,121,117,237,101,99,67,119,221,240,131,7,139,159,73,77,176,146,10,86,147,107,148,159,89,190,122,236,52,218,195,136,20,28,176,243,178,199,116,242,40,133,42,89,4,44,109,142,151,147,233,186,231,191,56,122,191,199,46,15,216,100,85,144,148,204,82,249,231,231,104,165,151,203,236,150,140,72,222,177,14,158,145,71,123,19,142,154,179,136,94,51,30,168,215,190,157,158,104,22,179,105,89,109,98,234,27,213,32,211,48,25,35,131,92,175,202,36,253,188,171,203,173,197,110,178,75,165,148,244,137,51,76,85,133,112,2,219,220,85,144,237,137,246,79,146,211,168,117,177,214,84,188,91,167,100,10,45,146,209,55,15,247,206,133,79,25,157,150,199,26,90,32,142,231,120,2,37,189,183,131,38,205,228,187,85,238,202,239,216,59,122,169,250,142,142,210,236,207,111,158,216,174,136,157,174,121,100,174,195,215,148,208,158,89,247,47,153,26,50,55,62,162,233,148,60,91,97,133,91,231,166,250,136,47,119,209,253,244,4,130,76,134,229,26,45,182,133,37,92,104,123,254,160,71,70,148,186,35,143,251,238,161,101,153,223,187,196,158,54,181,166,50,30,39,237,143,216,25,47,84,195,214,85,4,156,159,234,223,184,237,227,183,111,127,192,205,21,129,236,183,185,197,119,180,247,116,223,85,54,242,191,118,164,175,101,70,191,252,219,135,154,231,156,19,242,194,122,220,42,203,50,223,52,84,238,240,63,174,239,187,254,154,243,251,73,193,95,85,238,31,11,151,171,189,38,146,47,220,179,173,190,72,214,110,110,125,81,51,31,69,142,105,195,240,199,69,238,107,249,161,68,151,242,137,234,203,170,254,123,9,151,27,42,141,142,106,110,80,139,76,32,217,220,33,219,31,238,56,224,126,201,103,245,5,230,154,181,237,75,210,238,37,198,27,7,174,74,221,211,81,122,33,59,217,136,115,170,113,79,255,119,79,233,164,147,49,198,103,232,101,78,139,101,166,173,33,75,171,111,184,218,147,233,209,50,235,220,217,38,53,237,241,11,135,40,203,158,177,191,156,215,114,117,205,122,223,172,173,77,31,215,221,195,149,29,148,36,19,165,116,199,171,220,105,62,65,34,222,81,244,241,72,227,93,127,212,230,154,154,83,249,117,93,249,186,185,92,91,237,202,29,93,71,247,142,54,154,205,171,55,93,181,164,45,243,177,136,245,229,206,252,252,184,119,69,77,171,122,186,58,181,41,55,163,14,229,235,152,107,116,88,23,39,134,198,158,86,88,190,241,213,214,228,44,185,189,235,171,82,63,212,5,90,109,94,35,71,175,215,245,143,23,30,200,111,92,99,194,180,50,92,42,154,158,254,120,204,202,149,147,112,255,165,84,38,74,105,75,222,196,54,2,87,180,190,148,33,123,167,89,134,245,189,109,61,87,116,106,138,222,150,184,228,157,31,111,179,91,162,251,103,41,170,104,177,110,40,94,26,178,189,146,247,236,200,247,174,23,30,250,245,62,39,149,231,127,92,214,223,237,80,42,74,221,193,191,161,226,17,183,119,148,177,181,95,61,45,123,133,168,234,195,205,41,2,193,112,237,253,99,174,229,79,204,63,31,116,240,201,21,229,29,23,47,215,190,127,117,173,241,98,228,198,17,234,101,237,231,174,53,237,222,254,181,189,46,103,42,221,52,189,82,238,234,93,143,189,230,211,155,213,76,206,177,119,120,48,248,168,171,96,154,52,92,73,105,203,162,45,58,68,171,201,88,246,234,161,73,81,247,115,246,61,53,252,120,107,214,141,221,36,199,22,25,243,175,11,252,223,5,55,51,171,191,243,19,183,230,209,30,168,250,189,121,108,51,106,89,31,171,235,17,63,162,165,249,229,183,202,219,215,163,253,203,134,61,204,142,125,50,175,201,255,197,46,157,205,151,131,110,70,212,133,152,198,43,124,155,40,127,32,233,245,252,155,33,45,215,2,49,54,15,158,167,12,65,46,55,162,151,63,32,58,253,35,165,35,141,66,57,129,89,59,222,109,152,53,183,198,237,116,144,98,198,186,215,57,54,244,56,251,237,221,252,35,14,252,219,115,211,236,152,236,147,59,203,184,109,170,218,149,159,15,47,249,112,125,156,206,171,39,195,47,252,216,254,246,174,126,3,189,37,196,78,79,79,207,178,173,179,178,107,211,241,101,123,118,95,240,125,100,111,16,175,89,220,232,212,222,109,238,255,98,87,241,205,19,50,199,77,118,172,186,240,98,237,41,187,84,82,113,243,246,179,83,110,63,42,102,122,212,237,232,172,140,252,154,208,243,242,205,235,188,243,57,198,219,155,123,122,122,156,108,34,139,110,240,162,222,50,68,70,223,94,238,189,33,227,86,187,228,83,212,142,83,171,69,53,41,130,132,234,62,152,221,152,108,196,217,216,52,119,85,178,186,115,246,170,248,218,165,189,118,79,221,253,221,13,46,108,73,219,245,245,208,204,229,251,102,211,90,226,13,211,190,93,172,156,145,241,168,173,174,212,99,207,119,94,32,255,144,21,245,106,232,240,154,155,111,22,123,94,151,143,208,20,221,75,18,221,241,244,93,8,223,25,63,201,152,155,211,94,213,219,113,161,129,81,158,229,240,204,103,215,205,168,73,31,63,63,114,184,187,53,191,82,24,211,176,121,239,72,234,167,123,6,9,38,95,159,95,139,47,126,32,77,247,217,35,93,185,239,90,48,227,70,117,228,59,143,130,167,218,102,134,79,40,111,69,203,71,225,2,242,171,140,108,104,125,115,242,84,2,249,249,248,75,191,125,77,143,246,126,114,105,199,13,99,31,233,141,74,215,229,86,115,251,142,242,44,202,115,220,79,232,40,231,24,10,143,81,20,166,112,239,133,64,217,41,126,137,138,155,199,191,187,223,210,245,237,211,116,118,131,111,177,77,218,210,93,135,221,151,245,189,26,221,180,208,111,75,164,65,202,174,175,117,90,173,100,179,248,147,177,75,235,181,228,85,174,68,116,53,236,27,54,99,251,173,239,207,109,138,94,236,238,61,32,99,158,167,181,125,183,127,89,107,22,121,215,97,243,172,181,175,141,79,125,218,243,233,158,1,255,254,242,209,60,179,241,182,91,164,11,12,33,221,237,159,125,38,117,229,111,187,144,177,219,242,13,169,108,242,147,147,206,238,41,201,129,79,221,62,190,245,232,175,151,139,127,109,177,109,233,7,111,219,31,51,10,251,62,212,45,59,90,222,81,113,183,59,169,54,183,248,135,115,205,226,206,37,70,95,30,59,11,28,246,244,28,169,248,112,115,74,222,15,101,238,1,149,222,105,101,166,253,70,182,159,74,219,47,220,125,125,207,178,115,79,111,195,11,254,159,139,106,227,228,38,71,113,170,253,19,79,164,188,56,218,209,84,126,151,185,167,119,195,179,152,248,137,97,86,31,234,213,100,234,87,232,199,28,150,195,209,116,235,176,233,82,219,248,19,90,196,96,78,1,59,24,154,124,238,74,241,101,87,198,147,181,26,175,161,3,2,149,97,138,43,133,190,15,34,125,140,94,135,207,226,31,178,154,17,177,108,139,143,106,253,233,93,207,99,151,253,40,233,19,26,84,219,124,205,114,189,147,186,236,77,111,76,151,136,30,16,186,24,14,16,10,135,146,26,191,8,106,38,165,24,186,135,143,125,251,225,86,58,247,199,178,158,7,177,186,19,63,239,222,120,49,195,180,238,123,215,11,237,249,33,230,11,212,221,247,44,254,254,80,112,151,255,58,82,91,107,74,142,198,248,153,115,247,79,243,59,166,56,180,174,136,251,227,232,135,39,174,30,179,150,117,223,118,184,186,249,190,40,108,243,65,219,41,38,243,219,62,222,213,78,216,63,99,119,9,235,142,207,187,146,150,152,35,157,187,58,119,76,30,161,144,54,90,16,99,179,141,180,174,192,180,198,240,251,136,238,186,218,221,79,91,215,233,95,202,15,138,188,93,111,91,115,141,113,228,177,94,125,85,174,105,7,78,54,15,17,169,69,91,93,67,136,89,154,22,42,250,244,159,90,58,207,125,71,213,73,41,243,194,132,103,123,63,10,62,229,173,166,91,155,143,237,179,118,109,8,89,248,116,189,217,84,248,193,104,102,85,247,41,62,175,55,61,90,63,206,237,162,215,237,138,238,79,87,151,235,70,23,118,166,229,253,56,178,145,117,69,142,49,254,192,59,235,21,139,215,205,240,63,115,205,96,248,231,146,17,87,251,222,25,57,111,11,186,57,237,116,47,93,215,118,78,228,52,149,148,149,71,246,111,117,221,184,45,236,243,155,39,243,135,183,150,232,174,255,250,174,168,97,85,213,215,194,252,210,71,55,5,242,177,242,159,246,88,91,169,215,121,62,41,210,249,227,202,228,6,175,71,247,235,138,10,123,187,252,69,147,150,4,20,216,125,103,157,105,220,243,98,200,5,159,87,50,39,31,207,153,171,178,41,224,68,50,235,234,240,11,194,196,173,101,154,175,214,158,93,83,33,251,241,107,3,211,214,215,61,247,220,3,255,145,199,187,219,178,203,242,75,126,168,244,119,120,38,184,218,219,231,142,152,124,41,120,231,183,7,251,47,208,219,46,20,216,173,158,182,167,191,247,69,164,189,179,138,182,127,227,182,253,125,223,59,251,89,51,82,42,159,146,159,185,251,197,231,22,55,175,183,210,255,110,187,244,41,141,127,117,14,203,236,108,75,236,178,102,123,158,202,140,218,29,189,10,207,11,189,170,173,110,119,218,247,42,103,71,115,138,95,152,139,157,212,12,41,233,19,164,162,121,60,130,184,221,60,71,70,121,157,252,242,17,243,109,110,117,232,143,97,93,73,80,127,222,210,60,153,191,229,74,236,130,160,49,114,27,116,31,108,57,251,229,240,176,233,1,166,43,98,166,106,112,68,53,241,67,70,47,185,111,242,226,166,28,235,243,183,48,69,149,59,195,102,236,132,54,208,207,135,45,222,16,61,165,77,105,223,134,135,210,177,63,38,59,186,21,209,143,219,46,218,242,88,61,176,59,62,225,218,173,72,53,147,238,204,35,130,209,123,190,237,109,80,25,70,111,220,175,182,137,228,62,149,62,156,51,174,148,127,216,54,163,32,130,177,237,80,202,251,55,139,125,219,105,54,166,234,75,225,91,47,183,183,184,63,190,153,250,106,145,95,251,58,215,21,138,33,55,238,122,37,249,170,41,91,156,79,51,78,153,174,181,73,205,62,49,110,201,226,91,31,139,87,27,230,87,245,156,105,47,239,172,218,54,86,211,227,216,158,198,166,23,249,30,203,38,45,219,93,241,220,104,198,206,247,102,70,95,159,83,224,175,201,117,97,57,135,148,179,59,39,111,45,57,228,42,236,238,40,239,188,163,85,222,174,234,241,231,15,213,75,15,63,85,126,170,89,124,187,251,93,169,221,178,111,87,70,103,24,239,79,138,53,108,103,77,202,126,244,237,120,108,96,123,245,139,31,31,223,207,26,189,248,236,141,72,149,200,104,157,3,185,71,198,157,127,184,91,102,251,135,80,233,231,95,231,155,247,10,166,246,15,45,246,24,126,107,18,134,208,245,86,151,175,157,175,205,29,114,219,141,168,119,23,200,228,229,215,150,93,61,89,218,98,108,119,229,226,166,251,31,83,10,180,38,82,30,140,236,221,102,11,233,195,201,114,123,233,110,190,133,79,26,125,160,174,153,187,31,60,218,245,249,129,213,135,108,159,235,177,140,168,250,101,211,94,158,206,205,157,208,171,177,94,215,221,222,62,186,129,209,75,175,116,139,188,123,7,62,37,136,81,236,208,127,67,187,234,24,53,101,210,154,142,204,68,46,162,108,178,211,118,215,71,191,55,18,196,57,243,99,247,244,81,14,247,132,169,108,58,120,196,97,169,209,240,161,110,142,130,101,253,221,177,235,76,111,153,44,214,136,239,231,223,62,114,164,229,106,188,225,248,241,187,141,63,222,154,229,190,224,214,210,186,240,172,202,175,245,243,185,15,61,255,152,211,255,180,184,42,94,246,25,137,245,57,165,115,167,149,179,213,14,189,91,122,187,122,184,6,91,110,215,124,184,51,63,223,112,199,221,27,154,235,251,57,95,2,45,206,151,186,77,223,121,235,202,171,170,214,39,43,52,206,187,196,154,78,44,30,49,164,224,137,243,153,34,13,155,157,247,138,237,25,252,16,140,151,125,53,238,191,172,254,214,160,179,245,163,57,113,183,227,171,18,235,17,228,54,108,215,99,215,166,233,48,84,171,38,123,167,208,118,73,136,186,241,231,156,147,49,243,140,111,191,127,117,237,203,197,232,157,15,22,132,110,125,97,234,85,251,116,181,214,3,39,110,253,169,237,59,245,78,188,211,90,57,35,45,243,97,151,250,158,132,104,247,45,198,253,107,31,116,39,222,129,226,171,77,150,231,108,40,102,204,225,184,87,237,44,125,126,137,110,208,196,61,50,69,90,215,183,94,119,228,173,146,243,14,228,239,95,114,12,251,39,221,254,76,127,112,58,163,175,197,243,250,163,167,55,38,189,43,106,96,232,48,26,13,247,111,22,20,113,247,79,101,91,87,52,84,110,112,84,79,189,86,19,50,108,237,244,41,147,168,206,111,111,156,12,123,221,151,251,67,68,51,85,175,92,119,252,117,159,111,239,245,136,113,143,202,221,152,222,210,207,58,178,246,189,45,228,148,214,171,237,240,23,20,217,175,149,76,121,158,169,105,142,125,233,237,17,196,249,170,20,108,54,211,221,234,218,171,178,111,236,120,89,167,7,210,6,97,27,201,14,100,174,195,150,36,69,235,204,165,229,171,23,42,143,120,232,91,186,79,250,216,108,247,184,8,181,45,199,172,14,91,184,182,79,93,109,120,35,87,79,116,163,102,138,168,179,230,164,182,242,37,55,255,38,222,145,37,190,153,81,246,123,139,111,171,37,205,206,142,177,170,125,190,207,176,95,179,184,81,167,46,109,83,183,75,218,39,206,123,179,97,109,159,253,242,51,13,202,121,139,139,200,63,230,140,107,187,201,234,179,130,70,126,114,219,241,174,240,29,73,43,172,146,22,63,57,171,237,193,73,43,118,125,65,197,109,43,131,172,228,93,236,134,147,41,177,75,62,134,51,108,244,46,216,110,250,214,87,39,74,43,213,172,112,137,12,42,140,94,245,196,231,138,125,237,209,203,63,76,11,112,217,172,134,184,2,23,220,78,143,39,24,221,2,185,195,29,246,111,5,94,167,167,7,103,26,233,110,126,150,62,174,126,151,214,245,81,107,215,11,249,46,109,113,121,149,138,59,238,56,60,123,26,21,245,80,20,251,52,247,220,54,173,15,199,253,154,120,174,147,12,89,155,35,30,135,217,135,73,173,217,25,23,110,210,144,253,216,179,118,228,246,238,248,225,175,242,212,187,133,73,76,173,29,237,231,247,143,152,172,107,157,87,222,97,124,94,227,185,130,247,60,158,114,131,242,209,75,153,197,29,188,63,172,226,53,222,78,128,61,153,31,46,120,222,80,40,78,172,89,182,49,22,126,29,23,86,27,28,195,240,60,173,42,61,242,0,159,27,122,48,182,248,246,231,194,141,150,154,230,171,113,91,83,78,86,94,190,80,74,53,155,24,41,156,53,188,36,198,91,209,80,87,222,152,155,105,76,61,127,238,233,84,178,136,99,200,200,90,61,205,183,103,222,219,211,133,22,121,221,237,203,175,221,8,177,49,94,153,227,66,63,97,182,163,65,62,229,161,237,18,134,26,235,81,122,252,42,231,186,167,78,55,214,117,31,10,235,155,50,116,75,251,243,174,23,123,60,58,246,188,252,113,149,166,59,46,169,249,94,234,144,241,218,93,77,254,105,138,242,187,10,251,90,46,94,127,212,104,196,213,211,92,186,193,169,200,135,179,61,223,164,247,214,209,128,13,93,140,38,65,180,193,139,112,135,118,153,221,194,180,228,229,93,220,55,143,53,234,106,87,78,144,247,217,177,255,157,232,213,201,132,22,197,98,133,196,96,85,137,251,167,164,180,197,205,161,134,176,151,106,250,68,145,255,177,254,138,239,139,157,207,218,14,174,59,99,117,249,198,148,140,137,14,187,246,190,92,190,110,229,187,172,232,197,91,238,46,109,152,189,234,100,240,76,251,228,81,134,179,223,38,238,143,222,105,189,52,91,254,163,94,125,183,111,130,85,92,109,164,118,213,177,250,134,228,39,11,250,51,75,62,12,79,50,12,155,239,224,210,127,234,176,67,234,146,58,247,234,133,43,242,159,108,191,61,198,106,234,161,228,186,83,71,118,252,232,86,185,250,220,237,82,225,234,5,127,180,93,207,178,29,101,191,246,192,163,4,7,209,168,2,29,3,107,79,231,87,89,6,218,235,74,76,151,126,123,57,164,110,107,126,229,225,37,15,231,127,237,59,81,191,254,71,215,18,95,167,105,111,253,166,245,250,167,125,222,150,88,241,166,164,89,93,14,133,63,87,251,229,43,87,247,245,51,226,167,18,172,243,28,47,233,183,244,216,84,93,231,123,55,62,103,208,129,66,124,57,108,217,193,82,142,104,223,151,194,203,33,63,150,116,53,114,216,194,227,222,106,181,25,231,55,219,124,144,74,27,58,38,60,110,109,201,92,250,43,238,230,107,79,221,43,44,199,173,75,116,146,62,17,60,132,187,190,248,241,105,196,26,46,109,205,136,228,191,218,63,195,175,86,122,37,124,241,240,147,0,174,229,177,115,46,155,70,58,188,188,179,37,48,251,35,243,216,205,165,251,131,199,217,143,151,139,173,74,238,205,218,184,235,203,147,11,62,15,84,143,27,110,203,152,186,251,219,171,11,155,175,244,101,60,210,253,243,5,60,102,154,199,188,216,125,109,182,89,54,69,19,14,28,142,82,173,223,221,251,14,214,236,154,154,49,59,62,106,169,223,165,70,214,181,145,58,204,230,37,197,219,126,244,117,123,74,23,143,91,101,104,246,181,206,59,205,220,252,233,25,11,168,194,52,227,69,226,60,13,231,134,241,39,23,180,81,26,248,86,184,217,119,223,15,49,160,107,18,147,137,56,24,27,92,48,108,241,179,199,11,162,230,105,208,158,70,126,64,204,243,120,87,247,57,138,186,134,47,203,210,78,66,55,54,48,43,231,184,110,218,22,102,151,98,252,100,204,186,130,217,116,45,123,199,169,147,230,153,141,79,201,188,158,106,46,42,82,140,208,93,57,198,129,231,181,184,157,164,252,20,49,198,212,122,59,122,245,74,87,222,173,123,99,123,166,245,244,147,12,122,241,115,79,197,46,163,198,25,85,49,38,187,206,125,110,125,224,76,167,214,112,106,77,60,226,170,62,15,203,221,99,231,120,243,81,138,145,134,197,133,135,47,185,175,190,178,46,175,37,63,94,83,155,106,34,120,104,171,173,185,178,183,238,92,45,245,207,99,45,89,174,249,155,30,230,110,48,56,175,187,184,189,96,239,70,255,239,95,46,80,63,188,206,184,180,211,103,143,180,226,1,217,175,83,79,176,237,95,252,176,164,23,142,189,94,61,57,247,168,244,220,21,152,96,244,27,7,65,143,25,159,169,81,4,58,238,149,127,62,219,154,113,199,112,244,98,227,6,171,138,157,121,31,114,38,190,13,226,165,20,88,154,156,15,147,90,190,115,104,215,189,239,241,67,63,94,61,18,199,104,54,156,157,57,142,28,31,176,239,254,243,243,148,172,29,93,29,171,253,252,82,174,15,217,118,64,65,89,37,155,95,126,246,72,135,205,71,135,181,43,213,28,244,111,42,223,30,106,178,252,244,33,227,239,61,95,142,28,89,101,172,161,112,208,82,240,176,56,125,119,216,98,110,10,175,231,238,251,87,215,92,15,87,43,207,211,114,141,56,19,198,187,47,91,166,109,183,86,245,208,93,205,250,142,135,19,178,17,139,66,16,231,188,42,194,65,105,205,252,207,30,151,172,135,152,158,238,139,140,37,201,23,60,77,149,9,52,40,244,212,217,227,185,67,57,43,247,147,48,132,190,117,219,71,116,155,54,253,30,34,103,38,233,77,34,198,255,230,200,212,143,73,121,196,172,218,224,24,158,181,75,238,205,155,55,186,90,74,95,171,212,114,199,228,62,111,157,218,192,180,237,99,104,180,112,83,140,121,236,222,215,42,138,169,143,31,63,14,213,208,61,20,54,253,97,109,214,182,94,122,249,98,51,40,101,177,127,204,104,251,230,103,110,222,211,74,63,213,44,134,239,167,155,109,223,185,46,239,253,26,167,224,140,217,129,183,39,184,230,169,239,177,221,156,176,126,227,143,195,195,44,166,28,233,41,249,232,214,173,248,133,25,208,8,39,184,171,101,167,110,63,195,255,212,83,125,233,131,210,168,93,47,182,156,205,165,246,125,251,160,195,253,116,98,59,55,32,99,95,247,92,231,26,203,99,194,23,247,175,46,205,126,203,44,162,217,206,119,56,81,177,58,88,207,254,154,212,81,123,184,235,249,201,216,219,5,228,107,220,180,248,194,151,249,147,194,77,46,210,58,43,187,14,115,106,77,138,201,19,186,27,107,100,242,190,187,239,176,124,215,80,35,160,53,180,183,188,232,41,186,23,223,136,75,215,47,114,220,163,225,241,187,43,207,125,177,53,27,53,96,191,218,75,102,175,213,180,252,64,218,254,52,191,205,14,219,191,150,233,223,77,136,50,142,185,124,1,190,75,125,152,105,211,241,71,136,214,247,222,174,132,49,179,86,88,72,103,191,57,253,199,57,183,139,141,156,163,237,129,75,78,174,136,62,188,116,87,143,139,195,171,201,113,212,87,87,195,58,38,89,117,86,247,87,37,105,213,132,48,135,12,29,113,240,137,171,71,165,217,202,165,107,247,94,62,184,154,242,89,235,244,21,232,251,179,226,94,254,204,101,147,181,253,221,203,118,232,233,14,129,113,213,172,172,156,227,251,234,211,54,99,98,114,67,206,255,71,200,91,135,69,213,173,255,195,206,8,50,128,194,32,37,32,48,8,72,72,137,48,52,12,168,164,12,221,45,37,45,221,48,8,138,138,116,73,131,116,119,55,74,11,72,119,119,119,215,123,17,62,103,158,239,239,92,231,253,119,174,189,102,173,125,175,187,63,159,125,219,1,78,27,42,177,112,243,3,113,25,64,33,15,243,112,248,94,122,99,217,10,36,31,40,181,67,163,248,59,221,184,27,222,118,61,40,192,121,115,240,179,7,7,229,71,160,160,166,155,119,152,0,22,233,52,70,242,183,155,55,115,193,7,164,124,59,165,55,126,236,137,164,215,34,4,127,176,224,164,143,245,116,189,148,175,183,17,71,127,181,13,177,47,100,40,22,248,57,122,52,26,48,221,148,108,124,253,236,4,38,24,188,115,241,240,14,82,163,80,0,224,106,140,193,231,118,193,206,195,46,124,199,163,13,117,237,105,250,229,138,114,91,155,63,5,245,63,186,53,15,68,241,202,168,242,160,69,102,91,48,50,74,47,77,48,100,21,219,144,69,99,95,37,165,45,192,125,2,140,54,52,98,222,67,102,167,216,66,138,164,127,58,243,98,0,160,80,132,169,34,61,50,24,133,123,149,193,146,133,107,78,190,122,98,119,165,196,23,24,101,70,236,235,42,38,252,15,29,30,161,236,230,71,164,191,184,238,106,198,1,139,221,20,163,84,255,3,76,66,166,242,17,174,211,26,206,60,231,167,19,149,205,102,240,126,28,88,188,35,144,24,47,255,125,64,147,87,149,154,75,86,161,189,239,109,231,182,10,31,2,153,51,235,149,179,252,143,244,45,80,179,60,123,95,123,130,208,29,157,31,72,91,162,128,223,201,214,249,130,11,72,168,187,3,159,198,12,125,185,221,131,84,2,65,55,203,173,232,44,163,138,116,109,138,42,117,177,95,112,220,150,199,127,230,214,228,22,144,209,192,238,0,200,81,76,7,138,212,181,53,158,146,221,235,228,203,42,192,30,100,179,125,117,219,221,6,129,44,73,145,84,113,42,2,118,38,255,13,34,146,27,103,40,41,101,139,3,139,23,242,136,142,82,44,156,144,36,81,154,166,160,122,249,119,143,12,77,4,66,186,159,3,7,245,21,82,246,160,143,10,60,111,170,236,248,16,98,72,159,20,246,113,222,20,4,9,32,2,144,80,252,42,28,96,237,141,150,71,249,139,145,0,128,66,234,24,72,234,239,240,52,224,27,120,39,107,226,186,7,255,46,12,198,105,161,94,136,213,42,244,150,132,180,241,111,46,57,140,151,214,97,80,156,134,220,116,5,133,224,190,199,109,196,215,108,163,214,229,185,58,119,46,162,233,149,21,244,107,79,123,96,200,27,154,149,205,143,82,29,215,146,45,96,170,3,37,100,149,178,236,191,68,58,168,23,194,245,50,138,217,35,28,161,131,11,4,65,226,129,30,81,47,224,147,251,228,147,97,176,184,232,95,255,217,19,2,9,233,176,75,86,68,222,147,48,143,185,122,85,147,251,188,13,55,31,13,128,114,70,144,103,212,203,240,40,164,253,152,16,220,246,186,158,165,54,247,142,177,255,223,62,241,119,86,166,168,117,113,100,36,150,246,25,216,238,64,69,190,165,214,175,179,128,118,237,234,39,89,224,244,35,162,7,24,142,14,81,123,121,109,233,97,134,248,55,182,104,138,9,6,183,217,157,202,242,32,221,42,49,186,23,165,231,152,253,36,201,186,238,221,27,158,200,182,213,211,111,179,127,225,146,53,12,48,184,205,124,84,246,5,210,18,113,140,50,67,180,114,180,228,93,190,173,32,152,233,213,77,177,209,63,236,36,88,156,116,237,57,119,156,194,128,253,47,204,143,32,143,169,243,49,54,150,5,241,151,234,107,225,78,80,153,61,166,198,252,7,94,163,6,0,133,84,140,37,87,62,32,217,9,42,80,176,250,105,129,8,232,57,179,52,170,42,149,224,29,0,57,170,41,149,62,103,117,138,55,135,248,140,54,191,230,78,223,117,165,88,135,11,0,10,197,178,177,245,35,169,14,4,167,69,141,183,165,230,98,67,71,196,240,67,29,198,149,25,107,66,254,168,37,141,211,156,63,166,254,53,249,105,71,233,158,243,109,61,57,4,60,169,253,192,128,236,61,167,162,96,83,31,4,109,78,142,7,54,250,8,175,153,3,163,137,165,148,94,107,152,119,255,255,205,186,230,208,220,186,249,150,250,129,215,82,46,24,162,35,154,54,93,147,229,190,144,9,84,177,208,89,185,110,197,76,21,222,1,80,196,169,197,85,32,113,14,232,166,82,124,10,209,244,134,60,111,125,24,49,186,242,24,239,226,122,81,228,153,217,59,27,193,60,192,45,153,13,4,6,183,137,190,148,125,128,12,254,226,131,216,30,233,77,186,209,144,201,167,63,90,190,246,105,152,95,151,68,197,177,117,41,61,78,239,78,107,249,200,233,222,226,139,96,8,100,238,229,51,57,17,164,197,178,64,177,203,20,62,246,152,27,28,54,31,113,239,53,155,141,249,115,138,205,176,57,11,47,123,246,212,134,91,56,73,11,129,144,62,24,253,78,140,4,136,74,83,129,251,70,119,61,109,44,123,155,240,215,103,110,52,8,253,93,29,111,149,156,211,35,178,109,22,80,211,235,27,197,69,48,3,81,188,92,140,140,86,190,32,137,138,42,160,125,244,112,34,59,56,88,83,128,9,227,6,221,31,167,91,109,223,236,92,34,139,82,12,249,219,189,43,160,147,142,234,48,150,65,238,254,131,105,105,192,157,120,134,245,16,238,243,54,162,124,82,0,138,11,33,104,211,31,106,25,109,33,225,199,140,121,52,48,215,119,131,187,81,2,132,65,142,125,67,242,248,72,181,162,52,204,83,112,164,57,98,150,72,72,29,124,117,8,177,155,12,138,226,114,70,208,203,83,92,19,199,244,70,127,32,36,64,20,175,130,110,191,62,32,210,218,175,168,13,104,201,38,246,169,222,164,49,248,148,129,96,0,10,47,97,139,201,31,117,139,32,254,123,157,17,146,125,187,38,113,43,215,151,169,167,130,160,155,45,24,171,232,123,128,180,88,22,8,229,110,169,57,135,191,74,11,193,26,189,250,181,242,101,69,96,8,63,156,168,121,119,254,8,245,86,97,43,129,223,254,139,189,13,17,78,220,117,214,241,146,22,35,135,94,201,126,131,139,59,214,47,164,21,93,227,245,217,189,91,77,84,0,92,180,25,22,235,167,19,34,23,141,40,234,16,81,26,191,221,162,194,194,199,152,163,56,176,59,30,31,96,120,207,15,45,219,56,99,159,200,151,221,87,190,113,93,16,93,32,138,23,235,64,188,60,26,210,89,67,49,222,161,165,242,209,198,56,252,17,79,22,69,220,1,214,96,252,162,164,93,55,88,30,110,152,188,215,69,28,189,114,173,1,14,212,48,88,75,230,66,74,1,146,213,124,71,192,63,189,242,39,15,7,94,219,90,157,121,208,73,174,95,50,67,220,39,190,127,46,29,237,42,37,173,39,254,54,131,204,152,201,0,126,220,232,104,24,201,136,13,158,197,185,102,55,244,169,209,210,146,123,117,169,181,203,54,210,167,73,116,254,148,145,193,207,11,64,185,117,44,87,234,255,234,133,44,58,178,99,161,152,154,129,113,155,69,247,113,204,66,130,174,254,249,2,116,203,16,122,238,213,23,135,25,19,121,115,98,26,233,85,13,223,116,22,36,33,213,96,14,217,88,142,140,182,102,89,214,104,129,250,200,1,40,109,24,67,133,3,123,228,190,232,142,165,71,202,134,155,196,17,24,148,55,116,32,24,172,101,52,37,117,230,63,75,39,48,148,209,82,125,238,225,60,220,57,32,142,159,1,65,254,36,33,72,40,244,56,196,127,80,74,114,231,255,101,62,113,135,221,145,107,178,205,58,248,81,132,140,26,23,192,166,106,142,205,83,183,183,50,55,51,179,154,209,193,176,58,52,64,20,59,35,161,114,248,23,111,15,107,236,204,181,159,236,146,164,55,237,46,150,171,184,134,246,175,184,6,22,192,167,108,233,94,93,84,233,149,211,64,1,167,73,67,22,83,250,179,236,123,155,20,28,64,173,255,92,97,6,33,4,34,191,47,249,10,128,12,23,168,120,192,106,183,205,11,33,243,17,24,233,250,58,92,36,64,144,158,112,157,48,104,59,171,248,55,27,13,254,95,182,134,40,2,1,190,190,193,191,123,198,162,83,81,122,241,102,114,244,191,190,18,53,53,184,147,100,48,235,101,65,192,208,191,0,76,227,66,21,70,100,182,205,149,2,94,3,152,86,173,215,152,250,209,179,248,231,129,209,190,63,246,172,168,168,123,191,156,56,79,203,89,223,32,242,152,44,66,180,171,140,111,206,145,237,155,66,123,242,114,65,98,138,90,123,200,235,14,16,148,6,155,90,248,214,107,127,222,92,74,253,135,134,230,127,130,166,243,168,107,18,155,21,225,240,218,157,87,107,130,119,0,181,168,166,35,108,152,247,230,173,46,80,189,172,100,88,126,111,62,67,140,80,222,178,37,0,41,223,218,255,47,172,136,225,21,227,74,128,191,147,155,88,200,128,193,115,117,186,16,24,167,176,240,95,152,45,99,94,229,6,156,134,140,94,121,135,241,154,62,44,36,163,17,6,78,183,64,14,199,15,133,79,135,110,2,136,125,85,52,250,236,209,131,127,76,27,197,171,96,180,164,15,185,113,21,4,220,24,22,220,16,92,118,193,174,162,2,147,92,221,148,239,87,175,194,198,99,251,56,27,119,178,50,224,223,48,22,124,101,162,195,89,242,24,72,75,83,80,179,124,94,52,123,254,140,18,126,203,124,45,92,14,49,18,145,214,127,2,167,158,24,2,33,29,166,26,92,129,76,125,241,128,73,231,126,89,195,17,58,121,225,208,183,205,196,128,103,231,34,140,139,58,60,56,99,155,234,75,133,81,249,210,86,131,60,105,250,105,68,33,90,246,170,240,97,153,45,71,159,104,87,50,73,195,148,236,17,248,96,139,150,111,8,190,72,86,39,3,226,43,119,97,208,29,93,60,104,182,8,11,54,203,227,216,105,142,91,245,159,172,53,46,187,252,197,145,177,53,48,215,97,226,48,123,152,82,33,143,119,115,212,56,148,29,126,133,176,10,36,91,71,32,48,150,46,81,231,216,150,30,194,189,147,226,204,198,47,196,102,158,79,127,197,60,27,242,121,29,96,19,156,140,62,166,46,68,60,208,221,229,129,250,65,189,57,33,185,212,44,172,19,58,151,184,94,98,142,86,193,18,176,225,207,31,44,112,225,196,88,214,46,152,11,86,155,62,153,61,204,205,216,20,176,139,113,42,30,226,139,249,39,94,208,194,96,180,62,217,226,49,72,250,164,252,5,246,104,8,157,231,220,116,252,3,187,121,212,61,199,134,58,223,88,152,189,154,82,117,118,89,89,0,143,97,245,106,85,56,204,147,191,132,121,165,63,183,148,54,216,231,97,121,94,160,90,241,236,88,183,12,152,238,141,177,26,195,119,188,88,14,77,26,247,179,242,139,61,251,15,147,181,25,85,151,101,81,97,74,204,76,61,155,10,190,233,12,183,142,4,196,162,31,205,204,40,137,204,63,252,140,170,174,21,231,59,130,174,215,99,61,216,172,118,3,149,126,70,249,180,100,19,185,79,220,216,89,57,85,172,197,160,51,52,145,203,45,167,246,151,251,163,237,21,240,127,255,3,101,77,76,96,250,236,189,205,233,13,245,39,25,133,193,60,118,151,229,17,158,234,86,105,66,31,123,61,244,246,173,33,48,24,45,102,182,40,41,50,252,250,9,22,143,189,250,190,183,180,123,113,240,62,123,208,19,4,66,11,104,231,89,68,199,118,158,81,220,15,141,128,246,213,102,252,205,10,88,153,97,48,218,93,201,55,168,255,98,93,138,158,112,172,215,195,254,33,59,25,111,196,126,88,152,54,99,61,38,233,70,226,170,214,163,130,64,182,91,247,146,142,144,124,20,155,18,36,173,52,21,109,249,7,229,199,219,98,12,116,147,20,56,196,237,177,128,20,103,48,180,113,111,158,140,184,202,134,91,13,146,101,255,149,13,183,204,175,59,111,14,180,138,229,106,57,82,31,92,253,102,151,154,117,232,87,159,130,175,255,215,69,153,98,244,25,20,170,246,33,25,4,0,165,13,221,235,69,163,10,203,103,120,173,149,176,169,200,29,192,36,106,195,105,162,228,227,197,209,160,217,118,96,13,59,215,254,181,237,110,137,34,112,132,200,216,161,10,72,52,19,8,222,31,237,128,3,203,5,135,79,96,66,148,27,34,209,135,39,30,124,34,45,181,14,224,233,248,32,37,20,146,27,177,180,124,186,3,72,48,45,162,44,70,110,110,190,245,216,18,92,30,25,95,214,17,49,108,20,165,122,117,7,208,133,186,67,204,54,24,149,228,239,97,109,128,187,127,54,146,122,114,253,94,42,4,218,109,101,12,165,76,182,200,37,67,8,194,23,171,192,162,22,23,135,62,249,231,213,77,214,109,4,152,83,37,251,203,53,109,187,112,185,1,110,49,166,156,59,148,255,197,115,28,124,60,172,211,124,68,33,223,227,237,123,101,85,206,126,126,169,148,250,86,66,74,56,255,80,18,21,16,181,59,42,102,42,43,200,233,41,23,128,16,212,243,101,150,119,125,141,161,185,193,238,154,138,11,126,253,219,53,154,213,47,21,132,207,116,119,224,118,203,239,119,0,9,223,216,105,251,145,233,211,201,192,145,122,35,108,113,26,178,34,89,186,135,16,4,34,23,184,13,18,175,84,113,42,217,42,173,47,188,151,90,113,189,135,38,58,24,188,147,81,254,215,42,110,56,174,241,193,20,221,179,205,201,183,165,206,13,93,184,61,85,7,251,159,70,69,61,10,8,100,155,119,47,177,12,57,72,102,192,18,156,11,243,74,50,22,231,28,174,238,72,226,166,184,158,222,29,40,144,207,199,88,9,218,125,47,47,143,202,64,117,115,66,8,238,149,139,236,254,38,143,156,174,25,128,202,56,3,224,36,52,251,29,156,159,147,174,100,36,0,52,87,237,168,235,221,22,188,79,177,191,40,148,154,114,19,198,209,251,156,148,116,233,145,90,100,136,77,32,84,35,250,192,142,213,36,122,147,16,184,47,114,199,163,0,120,144,197,126,46,162,43,52,193,200,63,48,92,41,156,210,112,155,1,128,193,59,37,203,233,156,255,89,90,10,28,168,95,254,33,232,229,85,85,125,47,141,19,8,98,163,155,18,6,13,251,6,45,137,6,195,215,110,75,19,15,63,234,186,16,75,210,204,106,90,70,36,41,101,50,128,203,44,106,70,141,120,207,86,78,233,87,45,129,40,224,45,193,58,3,201,118,212,1,253,25,157,169,177,159,244,167,239,37,255,102,237,111,16,8,240,32,224,95,17,250,151,84,35,200,106,239,196,113,96,79,254,186,90,105,41,55,98,95,29,47,178,196,39,19,98,253,71,221,86,80,65,32,5,87,92,25,24,146,217,168,42,66,254,88,84,141,50,136,58,166,8,25,171,40,119,126,186,3,140,192,201,195,17,226,53,97,124,209,33,246,250,175,137,60,132,64,126,37,35,187,113,67,96,43,136,162,107,69,210,246,42,99,51,64,247,218,109,98,95,13,96,160,42,233,150,249,223,132,68,0,135,140,250,116,178,58,107,9,229,117,211,227,221,27,42,195,68,218,234,199,98,173,54,63,46,52,143,250,30,95,239,182,122,149,7,255,67,0,189,205,131,65,67,135,181,199,15,29,208,31,65,175,254,145,30,92,198,53,187,167,113,185,109,134,190,215,42,246,159,61,1,64,161,255,203,251,117,4,156,246,84,110,36,247,230,242,226,56,131,97,117,22,128,40,104,199,7,193,242,104,119,64,130,58,222,253,221,83,140,248,131,91,147,145,187,74,220,135,115,144,29,139,71,193,63,20,31,6,159,6,172,171,211,81,131,253,2,187,227,3,188,75,197,176,51,163,141,29,21,111,189,67,201,149,119,40,101,46,70,54,240,64,24,39,107,139,235,97,117,55,63,244,122,135,35,82,102,195,6,78,183,187,255,152,54,32,97,173,132,145,29,121,73,18,194,217,46,192,89,154,123,242,46,51,250,47,97,20,48,12,150,248,100,218,212,242,98,156,102,60,14,45,231,206,95,228,57,233,14,32,225,13,244,89,40,50,209,199,8,176,58,243,123,123,106,43,37,112,200,231,74,184,75,146,61,77,50,5,255,104,137,202,67,8,36,36,121,32,9,153,8,33,15,1,247,153,60,113,246,2,239,2,21,226,95,63,68,1,111,201,212,9,203,126,234,53,113,114,72,164,194,90,152,165,150,138,185,126,61,94,28,8,100,78,236,165,156,36,210,141,60,244,168,106,244,92,91,221,36,179,179,121,10,202,186,73,191,128,213,175,71,92,123,186,100,132,206,204,104,221,245,243,208,110,53,158,49,254,242,89,203,7,228,236,176,6,29,133,233,209,171,212,56,139,117,184,43,14,44,94,8,80,205,231,196,35,212,82,195,82,247,247,177,255,22,28,216,40,166,78,78,214,156,55,161,246,143,175,219,6,176,151,30,209,36,175,136,62,121,17,111,180,159,24,214,208,7,236,19,164,184,93,63,202,143,9,6,239,148,239,167,243,252,71,101,195,129,230,21,156,206,176,79,124,162,159,111,74,221,64,68,99,135,245,4,60,179,117,242,147,48,33,10,201,173,100,63,95,57,63,54,170,126,100,47,47,235,1,243,20,60,88,183,159,17,12,253,26,136,5,64,57,195,205,139,255,236,151,180,199,2,125,88,38,0,190,40,230,100,191,233,185,215,161,1,128,66,252,69,172,182,200,109,8,234,128,61,139,17,185,222,27,70,27,49,230,59,233,87,47,23,9,112,119,204,197,46,132,29,148,172,111,93,15,236,224,42,157,173,245,77,167,64,18,210,107,160,96,53,159,128,40,33,135,153,122,55,19,255,109,137,117,239,247,79,158,100,239,105,28,108,79,109,245,189,155,103,143,158,192,96,45,225,97,41,177,72,162,122,5,44,175,114,221,28,231,230,90,222,159,253,113,29,32,49,135,98,10,106,206,54,190,109,228,27,189,70,162,215,21,15,103,17,20,255,11,64,182,2,78,191,177,36,184,255,163,55,55,26,103,20,7,86,103,239,177,117,241,14,183,249,184,100,238,168,0,97,33,121,117,97,87,42,241,80,219,43,64,196,87,82,1,41,105,0,161,178,61,74,114,141,230,138,165,248,133,234,113,229,239,241,242,226,69,181,187,112,118,152,201,94,113,166,205,225,215,11,223,230,43,20,48,24,45,201,186,40,35,114,95,88,25,226,34,93,97,103,239,52,212,173,242,252,33,58,14,172,206,218,163,234,94,199,254,211,101,221,169,232,225,87,124,181,7,233,252,215,146,10,67,253,206,202,212,158,45,49,142,92,50,80,107,39,122,174,141,110,190,242,18,95,206,187,170,187,243,120,146,72,196,150,103,67,44,121,181,252,180,110,173,166,224,89,29,232,191,216,155,235,52,95,30,161,48,40,116,79,135,242,42,111,143,77,156,93,22,141,136,254,163,240,203,226,175,225,224,79,229,186,40,170,133,57,33,163,13,240,58,212,15,54,51,156,82,60,60,237,249,121,164,87,71,0,189,194,177,38,79,253,54,75,39,244,177,29,113,251,61,11,235,83,24,140,86,247,129,184,45,114,58,154,142,176,123,63,226,217,243,5,45,91,254,43,10,8,50,149,9,227,253,208,99,30,22,203,120,102,182,149,85,159,206,116,173,173,74,64,20,175,42,99,115,122,31,36,167,139,190,164,39,186,119,100,73,119,91,234,220,244,169,119,140,134,254,105,132,219,92,213,139,164,89,245,180,76,200,161,133,254,186,79,157,189,194,197,69,118,67,135,170,254,248,97,71,240,168,170,152,65,33,235,67,197,28,239,99,124,5,0,166,216,173,250,123,93,57,22,54,202,80,100,245,39,2,50,97,37,245,54,137,185,190,192,122,178,172,132,95,118,188,16,149,44,17,206,212,83,108,194,177,60,146,109,82,52,161,80,97,219,219,165,81,41,30,199,239,170,55,235,203,17,166,235,207,167,152,83,177,66,31,193,162,243,33,75,57,127,38,211,96,144,194,143,132,219,230,157,236,229,80,189,139,80,106,78,103,114,230,201,80,77,176,20,127,249,203,190,47,66,6,18,255,97,33,15,87,124,79,127,112,115,112,58,143,145,62,238,204,127,117,229,60,17,146,132,169,213,49,191,137,7,161,190,213,54,203,178,42,5,122,98,65,17,141,179,69,113,92,42,4,204,154,12,151,28,134,126,111,34,88,95,155,87,207,19,12,50,253,252,244,32,184,246,242,124,147,245,237,175,207,84,26,18,185,202,127,150,63,18,106,6,120,147,187,41,119,114,45,62,38,244,50,90,230,109,139,177,232,158,121,253,86,192,220,178,215,234,99,87,145,21,244,1,150,106,17,173,248,160,54,15,57,206,59,5,128,243,64,228,69,240,133,134,89,255,89,198,210,28,255,64,249,215,35,58,140,91,84,149,190,14,148,160,56,63,63,135,236,78,19,96,99,171,157,165,117,163,89,150,178,219,113,44,82,62,77,42,16,170,175,109,175,45,152,30,233,25,77,186,236,74,18,177,91,37,169,59,76,127,100,228,215,15,69,141,53,101,147,173,117,59,215,91,140,177,11,194,100,42,131,45,116,197,77,26,16,48,37,134,246,77,246,176,177,154,140,62,12,138,90,4,154,123,5,156,127,104,170,141,142,117,150,118,253,235,252,63,93,165,132,255,79,119,234,195,81,212,166,77,185,146,105,73,6,122,175,107,91,73,205,254,128,90,229,242,31,131,174,88,202,77,19,132,193,118,80,99,5,251,183,190,225,50,148,213,143,154,63,40,125,220,46,118,119,245,207,247,7,195,45,220,79,71,51,85,189,230,142,14,39,156,165,204,187,3,69,167,123,248,229,222,246,15,122,247,226,127,210,101,121,117,146,211,173,4,29,183,233,77,250,182,45,206,20,78,24,165,233,135,234,81,66,144,231,224,8,223,57,137,90,154,238,139,92,38,81,84,251,25,252,247,3,159,162,140,59,128,255,71,42,113,176,199,64,208,204,52,93,191,210,175,223,161,180,247,183,127,229,114,93,3,108,83,117,30,57,177,80,219,209,202,205,154,103,139,113,238,53,99,219,181,151,153,164,127,100,44,178,36,200,90,28,23,99,104,68,30,91,122,97,66,138,121,223,4,169,181,199,85,124,121,65,64,166,74,190,112,185,159,235,174,113,113,50,88,11,181,68,169,4,191,83,3,84,10,123,198,107,122,10,29,248,252,39,196,232,189,68,32,164,161,35,129,170,200,5,112,62,98,245,195,96,103,39,47,246,215,180,33,83,5,220,79,20,100,206,197,134,28,203,101,143,162,252,233,85,141,141,141,245,124,24,75,2,70,45,106,199,207,31,239,251,38,38,185,125,244,19,255,60,35,68,238,126,150,175,238,180,156,204,173,186,180,184,77,177,113,238,195,92,19,144,26,235,36,254,84,50,146,74,46,21,30,170,82,104,208,90,103,139,214,22,80,255,82,47,183,250,32,136,226,229,39,188,228,56,22,157,15,111,162,57,101,52,221,142,245,57,30,209,165,174,111,182,253,208,47,168,82,210,114,181,13,119,235,226,59,12,97,31,84,239,205,30,125,87,48,168,233,44,169,233,178,253,250,120,41,209,127,76,138,95,139,146,196,162,42,208,180,100,216,192,106,41,193,91,220,204,108,247,178,148,53,188,212,252,64,232,226,53,170,217,204,207,163,237,89,253,133,223,17,98,195,247,176,201,24,70,77,11,125,93,78,150,83,153,90,14,58,43,55,91,150,116,133,219,69,99,204,187,194,202,206,152,171,247,130,94,156,108,253,196,214,112,92,231,124,86,139,250,67,60,244,114,187,153,220,62,86,71,26,242,231,196,124,109,39,130,207,185,100,168,166,153,204,249,77,24,163,218,83,231,205,234,210,211,229,222,84,255,246,46,77,83,148,1,92,41,94,138,46,254,211,44,204,153,7,228,252,99,146,221,165,35,198,153,212,70,196,57,202,92,113,142,11,68,249,80,86,139,211,170,227,133,168,118,69,53,179,249,17,86,215,106,54,222,176,174,108,74,109,74,175,177,194,129,31,147,63,7,90,63,22,254,83,242,155,61,251,115,118,105,101,49,186,19,72,130,140,179,20,229,193,134,112,226,126,145,168,30,173,69,231,36,193,56,57,105,49,60,188,60,190,202,46,99,9,156,189,231,90,253,93,56,199,250,224,14,245,249,31,167,44,84,72,15,32,65,215,143,75,216,188,114,29,74,200,137,209,60,132,215,105,160,210,63,96,27,84,216,201,45,231,182,159,169,37,182,216,25,51,222,105,146,83,46,124,225,180,94,220,234,56,187,59,186,157,26,107,245,181,236,40,222,188,234,242,226,84,191,246,252,192,218,145,204,126,204,146,213,236,164,104,233,173,24,125,160,58,239,79,239,7,225,181,234,167,132,195,58,222,164,24,168,105,218,140,105,204,33,21,121,37,59,119,221,119,130,227,90,124,152,171,191,207,9,24,252,126,68,244,252,173,215,217,20,154,128,104,108,49,155,118,12,128,9,162,103,48,121,190,97,175,127,178,183,204,116,199,0,223,31,131,54,183,254,239,44,0,99,176,126,72,176,206,207,146,0,147,254,36,157,99,51,249,1,76,230,42,112,74,175,103,211,99,14,225,154,227,14,139,54,10,239,199,79,48,9,25,223,236,92,174,22,187,135,198,86,59,125,69,141,102,104,97,179,91,83,46,95,88,201,100,207,156,137,102,170,57,122,91,62,235,199,163,215,206,88,106,42,47,134,121,164,194,69,238,186,214,61,87,181,156,104,63,169,107,95,190,97,49,216,26,47,232,73,76,218,254,73,145,32,47,45,128,253,147,33,38,64,20,169,39,27,112,152,81,34,79,128,92,23,55,32,16,62,247,202,8,95,141,8,65,126,228,232,73,15,124,36,212,164,173,254,209,77,149,195,172,138,29,201,235,104,37,67,199,248,174,80,72,4,39,52,242,160,171,64,181,196,52,93,253,172,210,103,126,167,157,153,153,59,135,243,50,79,90,108,43,161,126,126,235,100,53,183,125,207,136,224,254,87,231,95,63,89,68,28,0,195,70,214,59,77,106,22,101,50,80,235,197,78,198,182,212,2,236,143,103,207,36,152,131,74,3,21,196,184,250,245,219,244,242,33,129,190,105,95,194,143,142,95,229,156,165,107,7,172,75,101,204,60,68,219,89,136,178,104,75,224,22,79,211,57,158,197,218,30,154,252,32,129,70,238,146,199,160,170,12,186,167,114,222,113,217,206,92,139,135,57,71,234,126,182,109,85,140,121,175,60,26,195,3,133,239,139,239,20,247,122,81,175,122,206,114,184,146,150,171,66,73,31,206,43,127,126,85,208,189,242,93,225,47,12,151,219,254,2,211,194,52,174,23,199,139,203,47,85,44,204,0,141,246,179,67,64,242,74,73,140,90,169,236,142,223,199,127,169,251,102,168,143,40,250,254,249,176,225,38,223,82,0,149,249,153,31,202,226,55,182,218,80,244,212,127,228,52,199,177,120,166,176,205,164,81,81,182,220,96,218,150,159,167,6,5,147,188,46,120,215,253,100,121,164,216,100,37,0,118,146,59,174,85,50,110,167,198,193,23,141,74,74,230,50,5,136,168,213,22,252,46,140,93,35,234,41,49,121,58,113,168,231,203,62,16,16,89,101,103,74,115,94,181,237,101,150,46,233,20,162,241,16,250,49,134,145,64,47,127,206,49,102,194,236,116,221,254,189,92,86,246,132,179,109,199,172,160,227,98,140,61,195,199,33,221,52,83,140,82,31,166,10,81,83,188,55,201,18,76,225,246,142,195,199,235,205,41,249,133,48,101,167,252,179,93,213,5,242,203,163,230,86,218,212,79,128,152,212,56,151,54,82,139,249,146,221,161,74,82,92,230,233,69,213,97,243,74,51,253,52,56,78,105,36,220,231,112,202,83,241,194,158,221,76,185,86,74,34,68,0,139,101,152,107,253,55,180,63,154,209,228,64,77,174,38,250,52,153,65,165,224,151,89,233,137,90,164,253,132,155,218,196,0,121,187,69,135,219,185,58,145,41,49,207,233,227,50,33,180,157,232,146,84,201,234,210,243,131,209,85,69,28,76,245,24,135,153,47,59,31,225,47,9,153,171,157,14,66,158,19,43,23,24,221,97,92,34,12,163,12,224,178,94,104,41,95,140,109,183,14,123,155,6,117,224,56,109,176,16,35,209,83,126,173,242,42,97,146,158,30,231,245,223,254,76,216,67,8,164,79,54,40,26,25,84,240,123,18,95,221,167,163,221,80,145,169,162,170,22,207,89,6,94,32,176,120,22,126,248,39,225,229,248,139,119,99,110,131,154,30,36,250,111,187,170,243,245,131,37,161,129,184,112,78,65,63,158,141,50,42,229,183,163,102,84,221,224,152,10,6,50,125,86,247,105,224,161,122,164,235,225,184,210,197,86,179,64,155,130,251,145,231,152,117,23,159,213,144,142,183,17,228,231,199,103,107,44,17,207,117,133,119,198,226,143,34,184,249,156,246,2,186,19,69,42,211,87,102,92,52,102,36,26,37,227,236,118,59,56,42,253,15,118,190,221,227,137,44,68,241,240,51,23,159,183,72,116,92,107,14,251,20,179,149,186,100,99,183,93,100,95,146,59,253,22,144,69,126,190,36,98,190,82,86,58,225,212,206,231,223,218,99,179,57,161,225,71,167,224,54,110,216,91,59,238,178,203,88,65,240,201,37,214,237,196,136,39,105,239,225,243,24,203,38,34,171,70,124,165,22,195,56,215,5,97,234,241,247,63,31,136,157,212,249,170,99,232,173,45,167,182,135,42,105,46,151,196,229,172,186,87,156,72,109,51,71,181,47,143,219,79,74,2,133,160,31,39,159,229,86,5,69,255,252,224,53,187,63,252,18,138,26,203,40,197,127,156,180,86,50,106,174,19,34,225,227,56,110,59,216,106,225,182,27,149,20,19,116,87,197,8,31,96,130,77,136,103,236,210,90,44,238,214,111,211,163,126,132,246,35,242,235,171,191,9,124,252,71,20,16,168,24,76,149,138,212,171,137,79,4,121,197,184,142,180,139,165,106,69,65,35,86,149,114,2,198,133,239,126,220,14,106,0,88,198,55,97,152,81,74,246,248,248,42,231,203,48,16,128,85,171,165,44,56,126,252,58,24,5,17,140,26,0,18,28,230,164,52,52,98,120,216,200,40,116,201,77,181,78,206,74,214,147,130,225,86,2,37,100,204,80,226,119,109,33,116,5,145,112,35,195,125,244,159,116,79,130,159,194,191,5,203,159,197,118,10,124,113,26,226,154,213,225,96,186,235,76,199,176,109,243,158,192,61,255,55,227,101,237,197,126,46,19,139,162,40,126,78,40,253,101,150,74,161,236,60,51,111,245,187,158,164,25,186,227,49,80,14,167,59,9,221,15,162,139,189,84,1,219,205,115,27,148,63,195,134,113,140,238,131,8,105,117,247,83,13,214,159,152,76,101,117,201,249,15,135,62,167,214,158,29,119,21,168,167,30,20,6,141,44,167,12,227,185,116,91,157,174,151,54,103,158,196,6,223,197,226,132,160,223,27,246,211,176,27,126,45,98,151,77,23,231,126,161,242,29,190,155,39,35,90,185,89,227,124,20,49,168,136,15,202,229,197,196,40,54,134,42,56,90,97,103,170,135,174,195,18,110,219,162,15,0,64,161,236,132,54,46,164,178,37,237,173,135,131,158,240,145,102,35,106,135,108,119,145,253,176,45,131,72,175,119,57,226,37,238,126,97,32,149,78,17,197,90,228,122,127,102,184,105,81,183,112,43,78,123,56,115,56,207,70,217,75,145,242,177,53,225,59,195,133,110,43,171,140,117,221,101,207,6,133,47,67,84,25,146,81,21,179,212,231,219,118,235,209,200,91,180,46,118,8,243,13,151,170,118,55,120,10,180,39,206,104,189,243,42,121,249,55,23,185,141,155,218,250,88,210,240,54,45,142,204,143,147,119,253,233,213,104,3,72,167,50,102,52,131,126,206,46,79,205,24,13,13,168,89,240,29,119,218,215,4,175,89,148,61,12,191,142,219,245,33,199,187,102,220,213,13,92,179,39,106,127,168,53,220,56,62,60,11,173,245,29,81,49,201,46,14,234,29,5,229,176,15,168,247,250,18,20,248,166,228,207,250,241,136,77,214,184,6,179,85,59,31,218,53,187,156,181,210,152,71,113,141,238,126,154,105,76,25,247,217,45,101,29,6,165,187,30,12,211,76,172,79,44,118,60,75,42,149,104,254,224,140,226,245,245,179,234,186,167,191,71,252,163,194,163,82,158,137,182,191,53,179,158,32,2,33,77,160,26,200,141,148,68,253,185,15,88,245,26,208,121,116,208,243,45,81,180,66,28,136,94,236,11,149,57,126,234,20,101,38,94,176,69,196,167,19,95,191,51,174,24,231,129,139,246,114,109,152,237,202,187,59,111,192,101,34,126,60,149,228,176,8,50,147,105,104,240,46,123,148,12,20,130,38,15,31,218,70,178,97,134,176,213,168,127,237,50,141,139,204,144,163,104,126,207,8,39,89,172,157,116,59,109,117,92,140,89,180,107,58,205,122,115,80,88,193,127,72,163,57,227,186,93,204,99,58,148,247,139,26,142,91,171,229,186,223,191,115,190,233,62,25,42,48,97,176,153,224,94,70,221,41,80,45,80,109,30,86,114,159,156,159,87,93,172,90,21,209,50,210,70,144,121,25,166,6,133,247,190,140,67,79,218,221,46,103,99,210,8,153,30,43,183,158,15,166,149,198,219,140,230,119,173,120,19,119,145,239,198,48,164,122,177,124,80,132,163,202,96,70,21,191,5,85,102,28,39,51,11,177,174,52,156,117,155,28,173,198,195,251,167,73,118,149,77,154,164,89,193,145,226,106,134,122,221,9,151,4,159,127,114,155,207,120,130,207,34,247,65,34,49,30,144,196,55,83,207,35,176,209,135,112,213,175,33,201,152,199,180,246,101,208,251,223,223,159,139,177,208,186,77,116,94,115,110,55,202,83,77,243,234,239,237,8,112,156,251,87,113,79,247,11,65,40,184,10,246,190,62,83,242,108,105,217,237,18,96,78,141,117,138,36,3,163,210,236,101,75,132,51,89,253,17,68,251,194,39,213,2,100,175,61,233,207,29,99,199,243,23,255,122,87,49,217,154,110,34,50,167,118,94,64,187,238,206,176,237,160,134,15,174,194,150,145,36,105,178,156,113,254,142,63,223,122,17,75,0,190,184,232,96,142,198,124,221,93,108,155,249,82,93,183,243,85,173,202,151,189,235,178,46,57,31,220,211,17,17,152,202,201,35,180,177,65,185,71,143,15,232,126,215,107,206,54,126,48,221,14,154,219,84,156,65,36,172,51,206,145,115,188,116,185,191,105,6,137,31,116,113,49,43,21,52,215,243,248,39,103,251,114,7,144,0,213,121,138,139,44,5,17,72,158,72,228,187,197,23,147,64,139,74,40,186,167,133,206,251,198,183,204,201,192,251,138,145,106,22,213,10,57,149,27,220,74,121,209,88,82,121,148,220,253,182,97,22,46,179,36,230,163,125,233,114,243,30,104,100,239,87,15,222,118,141,18,29,230,90,90,205,5,138,60,29,221,168,62,212,44,37,243,95,161,11,87,178,66,104,222,111,15,99,124,230,210,199,78,162,129,187,104,65,216,6,231,89,167,181,211,116,182,11,184,246,148,152,32,234,174,211,110,179,101,136,191,68,223,47,9,203,8,182,173,110,8,68,97,227,207,204,108,27,207,200,82,74,217,197,64,118,237,46,156,167,157,239,112,34,56,228,50,61,53,86,28,40,180,17,94,95,113,65,18,66,161,113,41,59,159,95,144,149,117,49,205,101,102,213,68,181,54,11,215,151,107,207,206,111,34,62,113,137,239,218,183,46,219,76,189,220,151,227,186,56,154,13,206,90,83,110,255,57,143,27,218,17,171,245,171,7,10,20,207,85,250,88,236,123,238,80,226,85,74,223,69,127,221,248,4,160,128,183,94,66,54,69,216,211,169,145,147,91,42,224,137,59,96,96,152,20,238,29,98,170,159,140,143,202,80,20,140,50,69,188,199,172,214,92,203,71,178,176,148,232,31,214,157,40,162,166,247,90,226,173,224,67,215,222,184,221,174,203,114,211,226,126,197,28,155,203,227,46,247,6,89,225,69,229,108,67,102,174,153,207,148,13,102,39,198,189,173,213,91,13,62,233,76,107,77,245,4,36,173,114,234,94,16,34,75,188,184,119,51,191,196,196,46,20,65,237,148,88,247,84,34,43,55,107,70,169,31,228,38,204,20,54,46,190,91,169,62,250,28,191,86,100,241,160,11,167,241,181,226,136,72,28,231,107,118,190,181,173,159,95,219,220,7,53,236,147,225,164,7,110,132,104,81,24,23,76,12,218,221,30,247,36,92,93,93,247,120,250,28,180,162,217,248,13,101,78,69,120,56,198,109,122,223,49,254,158,252,32,79,98,154,231,97,90,54,253,105,163,57,150,72,127,213,243,222,3,241,146,253,165,110,74,126,246,205,108,6,237,65,213,78,77,117,148,234,208,23,153,21,189,225,181,41,153,57,105,120,160,191,104,60,53,12,150,166,162,78,37,140,212,3,35,1,122,248,192,255,44,15,18,100,19,161,161,246,212,7,95,37,244,7,227,134,90,195,6,81,102,73,169,252,134,6,91,83,245,59,204,164,203,186,18,143,56,11,38,222,5,198,216,79,168,116,242,29,142,37,125,47,46,46,214,249,76,249,149,169,35,230,48,153,164,163,240,253,180,80,4,155,81,16,230,24,131,50,203,228,140,168,121,62,129,223,174,63,180,181,206,227,174,109,173,175,10,250,232,100,143,166,77,247,107,166,22,221,196,96,83,60,89,141,24,248,211,192,10,94,243,138,229,167,142,135,227,246,227,242,118,80,167,165,175,207,114,108,82,37,218,34,225,143,13,251,250,156,59,63,200,126,60,35,241,235,164,179,127,23,31,179,187,145,150,118,49,223,211,223,223,95,174,97,137,111,94,115,108,144,15,233,14,162,150,136,30,12,85,210,84,8,113,159,221,245,186,216,182,195,188,96,83,103,200,43,217,57,105,166,206,155,18,218,38,90,227,146,46,249,21,21,231,178,67,151,191,58,179,94,58,73,208,222,229,150,34,25,181,32,252,109,56,4,129,45,112,246,126,27,253,168,175,2,56,98,51,225,7,22,207,105,27,160,94,88,251,235,77,15,128,111,136,6,15,22,230,144,191,62,62,197,40,35,123,199,97,144,224,218,62,45,182,193,52,52,189,16,199,234,112,222,237,30,231,184,16,241,176,216,254,65,176,169,192,22,226,238,252,136,73,110,232,94,161,209,167,7,36,4,235,254,189,11,122,107,67,249,172,7,123,249,31,91,132,92,238,133,135,150,88,179,102,61,29,211,73,132,51,76,5,199,62,221,104,36,212,10,121,137,197,245,139,186,108,179,230,244,215,78,62,206,51,2,215,124,88,211,179,220,170,39,47,57,200,87,14,70,23,57,15,89,140,147,226,108,116,127,186,204,188,13,113,42,173,243,211,240,232,208,176,58,230,172,123,72,78,226,206,196,47,167,126,193,233,175,244,244,77,64,135,205,43,184,139,188,229,10,107,28,131,165,252,229,39,65,118,158,39,89,185,243,185,232,237,3,2,109,207,141,47,139,186,85,12,99,168,57,38,28,18,171,246,7,212,236,184,53,108,78,106,45,103,245,198,204,102,147,158,106,205,2,133,20,47,134,42,229,165,233,121,253,6,7,192,44,135,78,174,173,185,84,71,67,196,142,165,135,92,18,151,138,197,246,233,45,228,127,93,174,16,2,71,136,49,161,133,11,169,113,182,4,3,114,19,133,217,105,171,133,147,143,187,153,13,152,18,135,124,17,186,171,19,134,227,154,78,160,108,63,85,177,179,233,126,169,182,81,190,72,182,60,89,235,46,131,179,78,196,58,201,179,253,171,161,132,118,72,55,102,176,228,254,35,150,58,84,235,134,3,198,241,134,241,74,123,123,65,42,9,45,122,119,146,227,183,245,95,205,199,43,202,149,189,99,70,146,11,253,44,207,181,227,176,57,167,238,240,168,11,120,17,169,93,36,127,120,170,243,99,39,55,121,135,57,110,100,7,115,151,57,9,125,151,217,5,107,48,235,76,81,138,167,182,178,143,228,104,179,246,242,130,73,167,252,44,120,221,119,199,36,64,14,117,95,106,49,14,90,32,243,102,80,203,189,58,171,116,194,169,145,166,159,119,85,41,11,116,23,46,115,161,195,23,36,139,159,186,40,151,9,26,10,13,221,101,121,132,247,214,42,187,184,237,117,163,216,141,35,73,3,2,128,66,10,127,64,120,0,164,164,185,4,15,84,228,61,130,10,94,218,53,193,181,195,204,195,11,3,141,59,69,217,182,46,139,6,60,128,14,193,176,120,183,96,92,139,209,214,115,159,72,204,3,236,39,28,69,176,4,206,182,88,4,191,12,182,51,215,170,195,249,246,229,91,43,69,95,126,135,164,58,126,123,244,92,136,204,253,204,146,136,85,239,115,137,197,119,143,106,130,69,242,148,218,173,6,204,249,164,96,120,1,16,207,234,207,15,149,17,38,141,138,150,38,18,11,134,131,104,82,103,63,223,215,10,51,133,195,214,94,110,23,187,113,237,141,132,90,234,120,111,218,6,251,240,58,229,234,85,121,87,232,162,131,50,109,136,36,98,158,146,74,63,111,61,226,125,208,171,122,188,89,181,11,31,150,110,39,151,41,163,202,204,157,24,13,189,12,146,96,178,140,235,61,78,237,210,192,99,241,85,39,94,144,9,54,86,218,165,83,32,24,13,235,172,213,137,52,43,29,31,240,5,115,207,126,123,145,100,152,27,43,70,144,80,218,47,157,116,201,125,62,159,69,126,193,226,232,39,31,244,57,84,145,128,197,253,193,220,167,142,63,109,142,10,131,203,158,156,13,234,26,141,63,216,254,218,13,16,120,114,137,190,124,201,107,230,241,194,10,3,153,27,150,102,236,65,193,67,70,238,91,4,210,235,177,30,84,178,85,161,83,119,244,136,120,97,216,230,188,89,77,179,187,216,21,30,72,41,34,62,89,227,218,78,195,84,104,56,144,165,178,49,204,109,151,51,81,237,236,195,151,105,176,94,60,8,151,29,45,178,58,88,139,105,13,166,105,143,23,244,28,91,74,148,5,164,204,33,232,213,242,119,162,186,67,232,228,244,206,247,7,195,25,75,199,10,244,16,89,170,95,249,92,79,108,14,179,82,80,49,9,90,84,77,178,231,133,63,103,87,110,84,80,123,74,246,203,46,100,133,233,230,77,208,48,50,189,173,47,23,235,210,8,239,55,14,203,26,164,16,112,83,223,168,208,243,15,58,29,250,107,239,164,106,8,67,144,237,218,65,226,30,50,202,161,6,73,27,100,130,147,104,4,17,235,244,172,5,191,135,85,98,42,215,213,185,41,234,231,211,45,173,165,142,189,237,141,52,203,111,36,216,72,85,143,52,158,48,159,47,93,68,199,143,173,150,239,72,198,39,226,124,31,127,154,190,33,235,36,203,125,190,145,133,234,105,115,22,73,131,15,87,120,145,229,96,124,247,111,27,53,0,31,128,125,217,254,244,153,164,8,31,146,212,142,140,129,229,85,112,162,197,167,103,63,6,55,51,209,173,240,128,160,35,10,109,251,54,39,129,140,200,140,100,201,103,109,255,225,175,106,123,73,67,71,67,145,81,61,105,69,72,52,219,200,7,65,155,147,208,215,111,209,128,32,7,38,240,4,249,236,226,155,99,175,64,159,38,225,99,121,195,149,175,127,89,128,223,192,59,201,201,233,52,72,193,242,11,226,158,167,105,19,39,25,77,228,231,188,171,77,146,80,25,104,31,46,189,244,114,121,204,240,115,168,123,47,180,142,251,118,227,135,16,72,72,246,65,18,20,25,35,150,175,147,36,36,124,103,79,115,215,75,209,248,118,254,70,174,160,117,181,216,201,35,78,154,39,115,171,175,165,170,111,144,10,176,118,27,39,54,113,4,253,191,168,139,127,1,131,175,202,71,87,191,252,2,58,121,219,80,210,185,70,179,194,19,181,159,223,221,252,43,175,231,0,97,144,126,150,96,58,22,210,161,159,225,230,49,87,161,29,52,128,18,66,101,242,201,1,40,188,248,239,187,186,183,217,152,130,112,43,190,242,86,175,165,67,175,95,23,13,120,22,122,24,31,152,254,228,95,136,14,19,56,9,183,217,113,100,88,69,175,30,237,26,127,184,101,229,9,131,66,171,158,220,234,5,140,0,5,4,210,79,192,79,191,139,180,180,3,231,15,22,220,89,154,123,59,126,33,62,144,0,128,82,245,240,179,136,244,72,71,79,225,199,218,7,177,236,156,253,55,252,6,113,4,34,64,169,67,82,31,169,186,97,1,196,220,255,66,38,192,132,122,75,178,164,218,215,34,149,80,225,127,224,252,143,155,193,122,10,131,165,121,178,63,106,68,30,190,161,128,138,49,30,245,177,88,129,143,166,153,242,26,61,76,43,149,150,230,7,197,149,134,37,127,85,144,14,143,246,78,252,65,175,77,129,126,11,214,129,33,144,144,47,6,73,15,145,213,248,101,93,163,135,205,8,103,186,69,147,32,213,213,63,159,225,188,239,53,190,23,235,135,253,22,148,46,64,200,205,126,115,98,120,252,64,37,177,156,14,146,17,187,16,230,45,207,20,149,6,171,204,186,212,130,211,4,128,160,16,252,60,195,236,101,1,98,220,29,243,237,252,206,9,118,214,155,81,59,91,138,8,68,64,169,164,84,227,127,94,182,10,63,15,11,78,248,224,9,213,220,58,59,172,17,7,22,47,6,224,16,106,49,15,121,37,18,105,243,246,175,222,217,48,0,82,190,173,42,175,191,54,66,30,69,167,239,81,231,186,59,14,159,157,86,154,84,82,241,199,133,32,16,216,64,168,137,42,83,30,19,46,246,221,69,50,197,97,111,147,200,219,105,64,218,64,20,175,50,44,36,251,217,122,3,113,163,23,14,72,28,236,42,76,73,173,0,65,164,19,96,157,146,153,42,155,41,190,153,91,224,160,127,108,69,129,25,6,75,91,137,250,12,68,82,196,63,5,64,15,183,217,113,3,193,182,23,248,178,237,13,86,80,20,112,203,55,132,47,120,70,197,36,194,8,78,255,215,240,2,239,0,40,174,111,240,239,158,188,184,162,194,32,71,69,139,12,159,43,81,75,64,162,57,114,84,188,245,40,242,125,253,222,254,111,154,76,217,151,25,12,230,249,160,124,210,171,115,43,193,116,159,112,145,188,94,158,23,21,79,193,221,63,108,72,93,184,65,188,8,181,189,164,7,212,190,159,32,155,185,80,221,245,232,15,137,186,60,116,0,10,88,218,163,174,131,40,117,243,196,223,66,34,94,10,142,180,39,248,191,140,235,24,10,159,176,101,142,113,155,255,50,228,121,7,232,134,57,84,100,68,112,191,109,254,12,19,52,255,67,251,251,164,210,157,98,145,191,104,228,27,162,240,255,75,143,199,7,241,156,50,208,207,105,137,24,170,224,217,221,224,66,239,191,125,187,247,145,183,74,210,73,121,94,190,189,240,198,189,192,74,80,65,32,253,74,215,116,82,36,163,241,69,105,8,20,220,168,220,244,61,200,191,142,171,117,155,14,92,184,77,219,36,183,169,150,221,213,146,82,179,116,34,164,37,212,168,99,133,158,99,158,61,199,100,14,98,144,107,198,45,49,62,186,161,207,238,38,255,242,5,239,123,212,191,89,218,127,251,80,83,18,83,153,208,208,15,205,155,195,247,151,230,181,112,45,130,254,61,136,224,14,32,129,161,248,169,45,114,175,6,232,17,175,137,59,76,233,245,157,48,13,200,24,4,65,32,252,129,208,32,214,104,205,222,159,36,212,150,44,228,204,142,43,55,51,234,190,220,1,80,72,17,71,26,35,207,163,2,205,49,146,233,105,185,31,230,37,190,16,212,190,218,134,150,25,188,196,216,179,17,236,230,247,112,198,226,229,241,51,207,91,230,173,141,41,224,92,75,240,95,19,100,183,36,33,239,235,33,220,231,46,38,246,43,215,131,230,150,214,187,71,113,132,14,62,2,8,254,23,199,0,29,48,56,104,56,233,92,90,62,123,203,81,199,152,27,131,180,177,80,245,189,215,26,16,216,85,240,248,231,171,136,45,21,4,34,160,43,91,106,28,201,56,241,222,247,54,14,223,101,93,19,20,186,101,149,93,179,217,236,84,37,47,160,108,21,144,161,91,201,10,95,57,191,36,138,244,123,72,146,13,197,64,33,190,95,96,81,139,139,157,33,255,205,6,4,153,138,67,160,190,182,161,74,246,206,15,172,59,247,216,202,109,76,127,126,243,32,63,8,12,222,73,8,253,59,96,239,22,71,76,114,239,141,141,236,188,153,21,166,12,243,124,66,204,93,250,61,192,94,98,135,163,161,50,242,175,235,249,175,163,7,31,130,86,214,143,5,43,202,140,102,191,218,109,223,104,16,10,155,54,217,4,221,57,166,127,223,130,117,129,13,87,215,247,89,194,91,102,62,3,70,159,65,190,108,31,250,191,236,13,115,174,168,176,107,65,16,195,11,171,118,71,252,122,190,147,233,183,0,247,195,214,92,95,117,145,156,147,69,247,185,34,74,111,209,193,78,118,77,245,123,237,97,140,193,28,19,14,47,39,220,47,93,35,158,235,126,218,219,24,87,251,116,159,232,137,154,89,113,168,205,114,79,35,166,231,64,206,92,146,88,176,94,107,16,245,235,225,185,61,31,186,106,167,253,32,143,187,104,43,246,242,103,152,53,4,58,69,91,222,95,112,105,218,232,82,163,127,228,175,195,86,86,86,230,18,188,201,50,56,209,120,236,150,123,146,55,134,108,42,127,173,218,193,213,160,67,218,119,151,187,19,69,26,23,169,41,128,32,121,239,59,128,132,149,119,104,226,30,72,37,72,20,186,215,37,185,197,229,11,169,69,137,168,132,96,28,32,200,134,229,47,7,32,218,229,8,124,60,185,77,222,26,17,94,203,80,233,187,68,227,108,49,169,117,178,223,105,46,61,215,68,98,17,178,219,37,160,149,2,143,25,73,75,63,61,220,220,60,80,105,230,110,207,64,95,43,216,237,100,181,30,96,224,251,114,1,31,182,206,104,248,254,129,199,40,21,30,163,247,243,1,71,72,176,20,191,202,85,174,186,60,86,190,155,161,223,212,205,234,124,96,234,120,182,221,252,242,139,193,68,147,221,152,165,200,241,140,15,243,195,215,62,253,175,159,199,55,28,23,157,95,21,101,68,124,78,54,65,126,248,40,224,165,71,64,20,47,110,97,30,25,113,100,74,147,52,236,146,89,243,114,147,95,105,207,253,144,209,193,9,254,241,202,2,222,3,56,62,201,242,8,238,146,221,243,202,90,198,26,117,229,27,54,244,182,157,75,88,52,108,201,189,56,72,25,170,235,201,134,46,83,254,228,80,213,128,170,228,134,239,173,105,14,214,171,113,50,92,244,43,105,49,234,74,241,48,158,105,199,44,200,4,52,100,175,180,211,196,185,252,0,124,237,213,219,158,105,180,90,136,48,36,232,63,78,244,231,15,26,53,175,236,240,53,61,190,56,172,101,102,103,119,251,150,66,47,244,174,9,45,38,27,170,106,67,173,233,127,161,166,23,225,39,236,184,41,176,217,122,85,29,41,169,91,126,228,61,28,179,46,56,24,49,105,70,43,26,118,54,24,101,59,200,145,239,185,56,101,57,118,253,83,153,112,186,249,122,124,170,228,163,142,21,185,231,124,232,78,32,150,135,49,225,159,75,180,185,75,96,102,117,32,45,242,32,69,70,58,22,189,190,237,17,66,221,75,93,45,230,224,216,234,26,106,169,142,242,27,142,252,125,34,219,15,19,52,235,112,162,150,95,139,101,82,157,71,46,9,111,28,44,74,170,248,45,75,170,78,167,121,57,66,199,62,173,238,5,236,15,108,60,37,217,219,164,88,205,234,150,60,201,29,86,168,176,89,225,20,196,137,170,201,178,152,100,215,171,255,112,188,17,57,238,48,235,59,14,10,93,47,157,212,140,117,59,49,58,222,141,187,100,232,101,91,210,117,93,134,154,141,53,147,187,51,184,158,236,137,229,108,94,94,108,94,134,197,93,236,165,110,236,158,29,239,38,59,31,110,180,242,43,18,99,102,21,15,168,238,68,248,129,11,38,51,40,253,121,133,106,46,246,115,43,233,230,248,207,182,94,18,113,152,71,87,29,78,56,183,10,158,174,21,230,242,30,77,221,53,227,247,85,31,75,129,170,204,185,84,51,85,216,174,134,133,164,39,102,243,94,158,237,178,26,55,203,136,109,101,115,141,215,30,56,63,119,62,32,60,208,250,90,208,81,50,218,246,25,135,82,93,173,111,112,144,176,184,85,140,38,134,106,116,197,141,224,122,32,231,55,240,202,255,13,236,182,128,67,106,169,245,149,190,69,208,223,113,172,121,218,1,251,159,118,24,143,254,52,1,249,87,215,198,36,177,70,28,227,71,89,172,15,158,68,176,186,214,84,93,182,186,56,238,20,171,176,186,14,8,69,108,31,63,89,238,206,86,28,216,232,125,125,146,51,240,58,53,98,149,161,218,217,46,104,162,186,225,80,147,59,35,77,233,80,245,124,153,202,182,248,184,105,201,172,170,241,3,63,102,162,118,192,57,123,213,94,143,196,124,192,75,44,203,228,33,219,65,13,253,185,150,192,130,65,77,231,242,46,168,208,18,249,229,145,72,55,109,130,243,102,181,82,46,78,165,40,131,222,175,2,86,192,105,140,213,229,112,130,38,129,205,233,64,105,77,232,227,29,31,173,51,161,154,243,117,139,118,198,210,137,25,224,35,108,129,179,128,170,227,133,40,86,151,163,45,42,73,181,172,49,251,75,87,38,18,165,1,172,137,156,131,170,184,134,223,46,29,231,155,213,91,145,37,131,22,46,179,36,86,7,195,134,165,168,2,142,16,4,140,4,29,12,54,166,124,87,128,28,109,84,81,26,248,177,86,215,76,205,209,4,139,251,16,86,215,60,134,103,218,148,158,234,127,162,71,245,196,150,138,79,108,240,79,135,45,143,34,95,159,10,196,85,190,50,112,203,23,229,143,42,124,85,243,189,82,217,160,67,133,97,211,117,47,249,119,76,169,252,2,179,42,147,117,141,250,211,93,66,166,208,10,120,113,79,182,156,102,133,109,118,224,134,198,74,146,196,34,241,178,172,18,101,204,138,85,143,202,97,255,10,44,113,36,178,202,173,83,66,115,49,211,250,242,221,125,163,76,95,231,246,173,250,106,159,157,179,12,242,53,34,58,29,196,147,199,175,242,15,39,156,9,99,140,187,248,14,109,4,159,144,28,235,122,124,209,249,249,169,245,43,254,179,57,15,52,178,247,114,45,195,160,251,81,78,253,220,29,140,156,120,254,79,135,117,253,249,198,222,81,240,92,22,118,241,175,10,203,239,173,143,42,9,251,18,83,239,46,116,4,87,110,214,168,105,186,238,43,112,29,12,233,142,183,248,112,202,241,28,98,50,87,65,54,171,118,253,222,68,115,202,172,29,191,134,178,234,86,174,151,152,88,237,117,207,181,6,207,79,123,147,135,73,9,156,203,215,156,237,72,16,177,104,35,76,171,247,7,10,70,205,43,217,35,155,58,219,244,122,243,85,242,234,132,121,84,34,194,152,181,152,152,107,142,126,56,79,124,227,171,52,172,61,63,8,102,44,25,122,194,20,22,197,244,251,195,11,127,222,157,207,206,76,29,11,81,22,76,167,155,181,181,89,53,39,43,98,145,226,138,99,123,62,58,209,245,243,113,252,77,41,163,133,136,49,198,210,119,176,22,95,9,244,185,253,65,45,41,160,208,194,187,174,95,249,141,109,166,177,37,151,157,60,155,33,57,26,149,80,12,101,6,213,162,22,162,168,228,227,189,149,126,9,232,184,141,220,225,11,155,37,105,251,216,35,234,241,148,46,254,221,44,243,18,173,19,216,70,249,98,236,47,62,243,222,163,71,206,165,188,154,206,235,236,131,154,193,79,37,173,28,77,11,90,159,22,12,27,68,137,253,228,237,105,30,62,249,128,138,249,43,135,60,211,83,82,162,108,194,105,181,188,100,66,37,174,80,222,220,241,242,252,80,35,224,183,176,108,196,71,62,235,214,149,162,126,69,181,86,227,204,236,129,37,22,18,28,60,203,213,154,6,213,68,47,73,179,180,173,11,66,45,37,187,140,189,98,183,65,13,251,114,187,163,5,142,90,21,155,108,169,8,214,215,100,78,75,9,194,131,89,168,111,77,76,124,42,51,36,98,120,106,12,154,253,201,55,99,57,246,139,115,93,179,231,216,77,106,9,173,23,126,227,84,26,96,115,78,33,130,224,150,251,102,40,83,18,204,213,115,35,189,35,205,110,104,166,123,189,83,245,158,179,84,85,148,1,68,30,51,147,5,191,229,125,190,66,144,169,161,42,128,193,65,28,55,235,34,83,226,235,36,79,19,243,21,95,2,169,75,8,76,13,58,189,131,239,193,160,166,200,44,17,158,29,144,220,190,239,234,8,105,223,175,127,46,17,158,245,39,254,37,196,39,60,39,64,255,217,138,198,96,81,147,99,18,220,83,64,131,237,72,55,241,35,119,249,148,212,163,251,43,242,81,214,245,241,170,227,230,30,9,145,85,159,30,22,113,237,156,200,154,144,168,190,203,247,59,181,17,56,190,242,106,108,198,141,5,199,211,216,238,202,33,81,182,112,114,155,63,130,150,191,33,195,246,123,207,69,104,22,11,32,245,97,106,230,203,41,49,60,123,121,47,199,237,48,223,170,59,76,127,180,154,242,64,171,208,14,34,229,124,63,85,151,20,60,6,36,108,38,181,143,94,13,40,113,221,232,42,202,94,42,152,142,23,220,97,142,145,53,139,50,43,65,231,72,210,236,226,90,124,124,60,190,233,166,228,130,24,141,235,221,83,107,175,189,216,103,38,228,252,140,237,184,211,74,51,191,245,19,219,158,156,241,221,94,105,237,185,100,214,11,215,48,248,60,1,51,148,88,111,14,139,167,37,88,138,111,254,3,25,207,70,89,98,213,249,193,168,185,189,122,206,254,160,150,214,70,217,44,22,225,183,207,254,106,195,206,174,43,246,233,125,123,250,4,119,10,235,2,80,223,49,144,99,134,252,106,31,202,215,213,216,106,44,153,76,172,47,21,56,155,198,182,186,60,63,172,28,175,118,62,100,194,0,169,64,12,215,134,122,231,19,253,249,223,168,207,88,141,2,160,24,107,25,153,57,86,130,143,78,77,1,119,7,83,14,40,84,25,206,159,55,63,158,229,31,62,49,73,159,10,49,43,186,51,101,116,178,70,231,188,16,160,214,67,180,244,233,147,163,215,151,6,37,204,22,82,215,189,110,86,179,147,162,185,200,47,135,155,5,237,76,215,29,183,1,245,66,240,187,226,29,149,40,117,251,113,219,72,126,140,157,164,157,194,59,191,169,195,213,159,76,158,111,216,147,160,142,204,96,182,6,113,24,138,245,40,61,18,113,90,136,48,28,195,67,132,121,251,102,85,46,253,240,105,48,113,109,125,171,36,82,169,201,80,102,212,46,229,182,131,91,126,52,227,19,92,98,73,146,72,88,217,116,121,220,229,222,38,76,98,22,98,10,215,42,28,53,66,44,116,185,31,251,96,170,166,228,14,147,199,157,235,14,235,156,146,142,109,70,163,90,219,141,24,25,86,27,76,138,239,228,157,100,41,45,68,22,175,118,184,121,51,149,77,1,57,62,38,232,71,207,216,30,34,38,47,14,74,125,129,10,98,0,21,193,248,187,24,96,240,10,194,87,56,16,57,62,80,3,214,165,243,44,208,82,79,12,20,151,109,30,95,101,219,122,112,200,6,78,145,40,138,4,165,135,209,11,194,182,211,23,11,237,33,254,139,173,123,17,152,115,186,231,199,166,27,172,49,100,57,240,212,175,133,203,51,21,203,69,150,182,5,23,170,227,250,191,166,248,205,87,202,98,185,245,199,140,249,184,197,164,98,20,115,136,9,72,26,117,18,221,9,24,148,211,26,209,231,202,158,55,151,119,3,82,163,173,196,31,50,188,83,238,164,10,192,193,102,252,90,225,135,41,103,109,52,37,126,87,185,164,12,231,229,64,66,78,248,159,203,243,201,203,214,195,26,251,31,152,247,134,169,245,19,187,214,54,243,24,161,196,45,220,13,132,106,139,229,79,55,250,210,225,3,26,246,26,17,92,214,97,191,227,4,164,38,46,167,238,174,79,77,200,136,132,84,73,227,33,242,187,159,215,158,142,83,111,60,14,115,39,127,112,95,57,182,55,197,40,94,48,92,73,211,241,53,156,119,251,149,227,94,183,200,184,161,115,254,185,229,197,11,131,223,239,99,142,10,13,92,9,54,74,103,94,237,59,93,52,18,254,226,174,55,251,229,133,234,217,160,251,166,149,58,8,91,224,76,180,147,115,246,190,163,184,167,112,40,19,180,173,61,44,109,196,23,171,240,206,31,140,7,143,70,222,54,138,74,17,14,74,138,0,202,215,157,252,4,46,182,253,137,239,59,213,185,98,85,110,36,42,184,22,194,60,81,31,7,173,175,200,166,198,182,135,49,249,139,147,45,129,178,43,109,216,250,28,72,205,118,63,41,199,63,81,145,221,199,38,106,168,80,197,125,186,158,179,74,192,203,185,248,184,253,231,129,151,17,119,255,64,171,213,3,134,161,23,118,166,229,171,57,149,227,159,159,145,168,132,118,254,20,70,172,151,140,230,16,115,106,76,247,12,75,100,147,86,186,68,240,244,203,73,241,49,138,144,218,134,12,181,16,170,49,60,210,195,34,119,231,229,59,177,40,97,169,237,140,169,120,183,245,164,74,147,65,212,241,236,251,115,115,170,78,124,37,245,105,63,9,205,31,79,160,246,95,181,121,24,114,212,172,114,158,42,154,134,40,86,13,209,150,29,169,218,143,22,181,228,199,161,226,184,31,242,60,184,23,17,117,33,146,230,43,187,58,81,237,173,89,72,172,220,43,153,91,197,42,184,86,254,42,57,87,37,112,153,188,43,224,37,54,159,252,221,239,221,236,36,199,163,251,22,37,181,199,29,22,99,182,228,104,44,179,79,11,78,220,147,6,215,150,83,227,54,62,8,91,170,172,159,255,194,149,10,90,205,29,212,142,234,94,145,184,188,48,169,156,234,42,50,234,221,183,134,132,107,216,69,188,137,227,31,71,205,96,64,197,4,70,128,255,104,137,255,187,28,19,213,158,13,212,253,112,212,156,104,44,167,112,243,97,73,61,165,63,38,116,66,231,13,139,67,223,54,62,121,240,188,23,249,239,239,228,99,7,75,125,83,103,181,85,4,143,119,11,105,60,229,46,39,119,235,169,57,106,113,191,245,154,49,87,237,171,176,152,45,124,128,137,128,108,203,94,123,146,141,132,154,142,183,230,172,114,58,146,179,91,233,197,199,172,122,220,163,35,238,95,254,137,45,112,223,102,164,140,42,155,244,116,64,205,2,181,228,220,19,155,31,100,243,203,131,103,33,191,153,236,153,184,238,178,13,113,169,246,88,153,165,135,159,19,168,40,120,56,185,119,121,48,200,134,91,82,33,30,64,90,234,186,49,86,94,175,233,188,158,125,154,229,82,62,181,170,117,233,36,163,98,211,39,99,21,125,15,7,248,64,184,140,156,20,63,196,180,148,215,214,169,98,142,243,193,20,222,122,225,249,98,140,189,102,188,92,44,170,20,239,246,43,150,119,127,32,165,147,21,171,102,113,194,22,192,152,145,206,126,41,17,126,84,110,213,180,37,135,117,7,169,206,234,2,124,210,253,160,199,153,30,81,194,173,205,223,136,130,215,54,229,149,8,127,199,9,8,136,37,202,125,121,61,143,222,174,144,122,154,189,254,123,104,69,207,7,158,78,96,179,220,67,205,229,237,39,138,174,233,118,60,15,75,37,196,180,161,175,158,138,52,201,65,103,123,31,184,54,88,39,100,229,70,186,140,203,123,52,229,217,202,159,89,91,188,220,151,46,55,46,53,150,194,221,175,210,205,197,128,253,160,170,156,151,13,252,80,221,117,191,255,181,254,187,33,3,110,70,157,32,111,184,8,193,59,105,166,188,217,139,213,218,139,103,195,230,27,118,112,53,54,206,31,163,63,15,6,211,251,212,99,216,239,204,141,168,164,250,97,218,188,146,177,82,175,121,186,185,66,162,36,46,242,132,250,116,45,186,67,229,228,96,25,151,44,115,221,98,253,45,116,153,188,242,194,150,187,100,198,100,124,97,184,200,228,233,73,62,180,208,228,185,107,118,120,165,193,186,253,19,254,206,137,222,193,44,82,114,226,161,253,71,177,151,99,214,93,146,57,195,15,160,67,16,94,104,168,187,75,199,136,99,100,133,129,237,72,77,67,57,251,228,228,229,197,33,122,48,220,158,112,206,196,248,199,121,185,118,131,23,122,43,191,34,120,105,9,216,81,73,105,179,55,34,235,134,172,56,160,123,52,0,10,110,238,242,199,55,95,25,147,44,187,90,109,209,62,192,88,174,204,109,143,102,38,68,43,229,221,19,124,255,245,158,187,155,77,99,123,189,239,97,45,121,21,191,165,93,222,59,49,180,111,103,108,221,159,185,73,149,226,19,157,26,224,250,131,17,102,164,91,230,1,226,218,49,91,3,116,113,88,240,161,116,155,175,165,242,78,70,69,147,61,75,180,254,44,146,125,50,102,245,119,93,55,190,173,139,19,96,166,37,241,52,228,86,31,140,232,197,101,15,93,80,113,38,122,0,92,201,224,221,110,174,97,111,226,187,6,209,13,58,163,85,138,52,226,152,19,23,31,172,234,196,236,108,203,130,30,122,157,218,68,86,56,132,59,215,46,167,68,5,205,50,104,197,40,118,162,146,207,188,218,172,57,53,151,113,220,119,20,221,206,9,173,81,131,209,230,180,163,211,68,131,151,94,124,1,198,28,48,254,193,17,168,135,243,172,135,112,91,48,137,162,153,172,253,170,220,172,113,150,101,218,173,216,31,80,35,153,55,180,253,178,154,213,213,135,110,35,175,152,200,198,93,172,26,34,165,236,78,90,31,156,68,87,100,84,214,5,100,127,16,110,243,39,67,157,236,132,33,137,246,61,78,108,51,80,162,164,106,187,137,68,236,60,59,250,228,44,126,110,207,78,227,187,148,63,25,31,16,243,253,216,251,159,15,152,202,210,18,91,130,116,221,182,125,180,168,150,103,67,63,98,18,222,59,63,217,151,88,243,227,221,105,113,80,10,40,178,181,57,167,230,161,87,238,14,228,17,171,177,140,106,44,89,94,101,135,194,115,246,151,34,159,217,102,55,15,175,164,209,216,119,172,188,200,157,145,220,224,171,50,104,44,78,128,147,132,175,97,122,66,167,237,218,71,71,32,213,94,131,89,235,216,189,75,239,42,127,152,12,0,13,45,35,178,153,184,147,181,173,202,80,101,103,93,185,63,234,118,91,134,181,28,52,239,95,30,148,214,198,60,110,198,0,146,106,196,115,55,45,175,88,144,99,254,139,42,25,136,184,152,204,150,236,199,57,192,41,146,137,213,243,188,42,102,33,30,239,191,102,57,4,101,98,201,111,17,208,102,96,177,5,90,250,187,210,206,210,156,185,31,108,160,192,253,126,92,92,186,119,60,245,0,195,209,169,188,94,76,63,29,179,66,111,75,134,204,16,30,181,81,44,30,102,130,95,129,158,112,252,128,104,225,115,189,202,97,118,57,199,160,127,120,52,75,14,200,101,6,97,203,176,180,60,176,162,85,106,32,133,223,165,64,7,131,2,192,118,110,113,246,10,74,82,93,107,191,13,160,195,1,227,57,74,18,11,75,57,57,43,78,138,155,89,106,113,233,25,116,27,214,81,216,246,134,126,227,191,24,43,251,126,84,7,88,79,254,22,234,253,230,75,244,162,105,120,9,43,213,214,139,141,47,100,129,189,16,75,32,170,205,196,239,180,60,91,197,106,80,195,126,56,196,236,176,156,58,92,189,64,26,253,178,189,104,171,166,81,194,150,107,212,98,12,87,138,183,123,24,20,86,241,42,146,137,201,148,130,153,241,109,110,227,122,177,145,56,23,38,119,25,133,155,106,101,68,73,234,74,150,117,165,185,43,126,118,92,226,254,23,6,150,41,134,45,237,222,223,213,27,169,201,133,56,108,23,246,85,95,75,100,152,14,30,65,251,233,156,231,227,216,248,52,45,11,235,190,85,23,179,169,156,51,190,159,205,165,76,81,177,31,183,61,63,129,90,84,37,208,85,210,31,23,55,205,142,243,27,242,173,138,39,22,251,236,229,150,164,95,232,140,154,228,242,141,247,43,105,145,78,158,44,190,31,159,30,25,84,53,97,44,221,172,57,29,32,29,36,145,236,74,185,212,74,148,215,58,110,83,170,210,208,125,34,153,96,152,40,225,82,185,242,29,181,44,218,183,109,167,117,197,52,235,194,114,165,246,45,25,61,165,249,120,104,130,209,42,127,129,179,200,224,15,59,21,247,243,253,113,57,41,190,249,201,213,51,153,68,225,1,201,47,169,167,66,114,71,42,119,100,189,207,83,108,191,26,15,206,141,117,139,144,147,98,207,119,69,102,116,0,169,160,10,19,92,39,181,182,27,232,207,50,219,23,134,141,107,52,252,56,134,101,150,211,206,5,94,185,87,72,201,57,227,195,151,35,13,247,44,236,114,155,223,134,169,24,68,156,197,246,247,153,19,60,218,57,52,205,222,232,31,25,121,99,39,219,1,9,201,133,50,152,87,24,102,151,187,156,43,212,184,133,205,218,124,19,47,237,228,94,45,155,254,169,244,62,87,202,177,35,117,91,96,82,229,94,99,92,109,151,203,194,139,154,7,111,39,218,94,174,126,107,84,53,137,97,134,162,180,61,145,62,77,162,147,240,77,67,67,214,59,27,230,248,90,243,254,225,94,87,122,191,39,136,59,192,101,140,163,248,114,87,184,221,250,46,67,117,107,215,197,86,86,212,254,244,99,251,233,231,81,229,245,62,88,180,174,174,10,130,168,220,69,23,95,37,137,230,7,223,30,239,231,186,175,155,22,249,57,59,55,141,242,243,179,118,115,123,22,243,183,170,24,198,204,243,185,208,20,63,184,211,253,40,224,192,45,92,49,134,59,154,132,195,86,116,149,64,238,209,203,46,104,193,15,126,49,206,239,201,150,157,41,73,237,254,238,91,245,104,252,105,86,219,141,132,163,220,175,186,142,212,241,146,140,170,158,68,109,48,8,52,219,135,60,19,43,201,46,95,136,220,78,118,47,145,161,159,118,37,224,84,213,245,101,95,241,91,245,245,21,181,228,135,232,133,198,241,57,219,133,207,50,218,63,10,169,173,16,58,110,232,29,165,240,193,182,132,18,183,174,23,180,51,117,166,72,101,174,254,81,114,35,93,217,238,130,114,17,240,156,205,186,169,220,107,204,216,108,241,63,245,233,146,96,44,14,81,179,76,198,223,69,120,2,77,45,51,219,123,87,200,7,239,126,109,222,87,127,147,235,156,50,156,18,63,253,245,217,64,91,222,242,145,11,107,177,70,86,173,31,135,121,49,66,148,115,230,46,248,2,229,69,169,93,183,19,79,7,20,149,183,129,88,80,225,112,108,55,216,37,47,243,121,110,147,243,15,21,254,70,87,5,76,140,211,142,182,73,221,67,190,177,78,158,77,117,222,53,79,54,140,239,70,15,114,102,8,206,205,232,43,103,54,206,108,171,12,153,43,142,158,44,106,204,240,233,208,25,51,174,237,32,98,224,242,149,122,247,249,201,251,75,203,150,221,190,237,43,29,67,123,210,28,134,106,175,194,29,131,242,73,100,87,170,67,215,10,177,208,132,130,253,58,251,32,39,137,163,162,187,185,157,140,19,253,61,197,85,220,109,44,143,11,26,24,44,237,178,152,72,9,233,163,198,186,51,244,57,119,21,67,247,173,46,45,243,104,223,59,64,80,8,28,118,222,229,150,37,248,1,39,33,106,211,185,241,252,34,154,116,28,225,215,195,190,170,254,44,169,211,16,245,233,222,230,144,174,191,45,84,33,162,208,104,4,175,244,61,199,132,131,28,25,120,39,166,175,164,119,146,204,169,19,72,171,129,145,119,218,34,245,216,224,216,239,209,243,31,237,58,106,52,45,139,217,119,233,41,47,156,252,186,182,227,253,150,211,132,3,223,201,229,53,164,20,90,113,76,216,36,10,200,44,135,171,59,209,149,30,168,154,84,226,139,100,45,153,215,206,218,165,86,133,234,104,196,191,164,241,254,237,162,242,210,27,171,63,214,165,183,229,137,89,190,139,47,204,120,140,64,131,237,27,193,238,190,49,239,80,199,233,88,75,219,32,173,191,39,22,119,139,86,20,144,148,248,203,115,109,216,234,148,110,86,45,139,146,138,126,40,83,242,59,175,62,158,205,26,220,21,19,223,31,129,10,217,37,141,247,152,195,162,134,229,17,182,173,111,171,247,199,150,12,122,43,202,237,13,233,93,69,251,127,63,53,8,243,71,41,76,130,238,71,79,102,119,171,185,21,182,221,39,98,165,122,106,118,204,107,187,210,87,149,29,86,34,195,158,13,45,246,38,143,208,213,239,184,120,31,22,197,110,162,104,150,20,184,46,199,131,90,171,200,101,51,30,135,54,181,246,10,117,202,143,123,37,45,231,11,134,179,16,66,158,39,195,28,166,15,235,117,214,240,104,101,222,44,244,31,47,228,56,126,145,92,150,132,186,52,160,233,108,22,55,49,128,97,245,162,32,206,251,71,245,14,214,32,57,125,239,163,71,189,174,184,171,185,59,36,254,153,121,14,90,171,182,191,213,60,40,198,57,44,229,136,42,82,102,172,21,243,220,35,161,102,21,165,190,135,238,188,254,134,40,39,137,119,0,9,23,67,198,234,47,144,204,113,151,34,94,32,103,223,181,125,75,178,243,184,229,179,28,14,236,142,71,16,70,154,251,228,83,223,130,174,214,206,160,129,60,219,98,134,129,128,55,44,162,49,103,196,95,242,71,140,51,203,231,195,212,114,176,244,147,67,21,173,38,143,154,56,198,44,155,73,23,15,107,247,122,124,142,183,255,136,153,141,55,171,64,104,237,88,23,209,215,62,110,82,149,158,138,146,254,246,81,142,79,30,162,35,237,77,31,203,163,251,156,31,226,188,221,168,74,212,214,123,89,211,25,27,10,151,243,50,42,180,149,115,65,180,213,230,123,91,155,142,240,72,210,17,240,100,150,14,27,144,24,154,180,28,53,156,219,254,242,250,184,184,113,33,128,200,225,178,241,39,132,127,102,238,55,49,87,179,95,244,198,219,247,175,225,31,102,146,60,45,57,63,24,29,164,249,190,202,83,73,127,202,76,140,23,252,172,142,245,237,71,28,243,157,185,214,176,164,149,56,159,102,159,220,212,55,17,51,147,43,39,36,158,18,9,112,138,59,221,67,41,244,74,250,85,7,145,161,58,131,56,158,214,141,85,179,38,228,191,187,73,36,12,77,122,143,198,157,74,74,221,162,160,102,170,7,25,251,114,150,123,138,246,250,116,204,113,185,124,180,143,30,138,172,227,109,214,14,36,179,9,244,44,111,154,176,23,125,25,58,231,40,237,72,109,165,231,208,254,131,80,133,101,188,255,33,60,222,168,29,96,183,26,203,183,240,93,119,236,137,15,195,140,220,71,231,3,126,103,179,139,225,174,80,172,190,182,82,96,1,235,25,250,176,167,223,233,248,112,190,234,201,219,140,45,85,177,153,22,230,80,158,134,15,169,193,52,207,90,84,243,113,16,134,229,249,186,205,11,52,199,46,235,220,95,187,182,23,159,73,253,194,68,57,73,135,125,152,60,92,74,101,108,212,71,154,211,245,71,2,104,169,240,205,88,170,118,98,84,98,62,248,193,213,47,131,168,66,52,186,169,182,184,157,213,47,138,114,7,63,174,154,48,197,23,219,135,41,191,69,79,181,117,238,123,62,110,250,44,135,104,111,218,155,124,65,76,40,213,122,201,227,96,124,225,35,214,218,247,150,92,65,93,180,159,164,125,103,252,244,112,139,228,110,28,226,252,248,110,198,147,212,229,142,189,44,43,118,12,161,92,221,197,227,243,195,73,139,70,175,29,142,97,61,92,251,30,49,154,249,250,248,229,222,212,74,52,50,23,136,186,240,238,219,66,137,223,78,127,102,81,71,173,211,194,53,223,25,14,206,142,168,141,142,207,148,73,245,157,233,8,94,240,226,167,190,175,220,205,225,137,210,68,164,184,56,239,118,112,20,234,42,212,214,188,113,109,200,130,43,94,62,226,164,37,195,238,45,252,255,216,123,243,104,168,223,55,126,24,81,162,66,182,34,13,81,178,68,27,178,142,244,9,217,247,53,70,100,29,75,178,102,204,140,53,165,44,101,169,108,67,246,117,44,49,24,12,73,66,150,236,59,145,117,152,177,13,6,51,243,28,165,207,87,253,126,231,123,158,115,158,243,252,247,253,167,63,58,239,219,251,61,247,125,93,215,125,93,247,253,186,94,175,80,121,159,241,161,234,151,11,110,90,76,207,69,17,190,22,252,42,145,95,129,218,41,16,156,52,112,56,227,237,214,126,217,238,51,254,100,142,104,133,200,122,35,162,21,33,233,49,171,177,213,9,39,151,189,149,131,67,183,198,124,230,144,54,166,195,223,58,72,111,16,131,219,239,187,200,77,147,26,54,165,41,53,3,92,247,75,72,211,242,220,120,251,177,50,38,133,84,72,5,86,190,175,103,13,173,142,92,91,135,140,170,153,67,9,186,79,216,83,224,100,226,158,61,114,123,61,27,252,2,191,254,169,70,49,21,193,200,204,188,56,119,242,203,204,225,121,214,167,134,110,25,246,140,122,10,220,98,215,211,46,84,141,162,162,113,100,8,17,255,98,63,33,167,29,147,186,81,62,254,168,241,164,197,125,145,187,233,156,74,209,153,70,46,116,180,98,152,189,53,255,102,35,115,151,56,204,102,114,71,93,207,125,139,65,246,173,47,252,81,63,154,167,94,12,94,227,169,174,68,123,123,138,36,203,124,110,220,120,240,192,160,149,56,135,0,104,111,117,38,184,58,55,243,248,120,50,92,218,155,60,6,124,116,195,238,235,202,46,137,62,166,96,111,161,199,38,128,63,201,175,241,164,84,165,116,197,81,3,239,202,162,35,163,217,197,71,74,108,20,146,116,33,47,7,70,51,64,10,218,177,217,186,10,113,38,106,176,202,25,70,146,6,209,172,2,174,150,242,70,92,16,141,171,217,219,115,240,213,189,63,55,251,20,235,246,8,78,217,157,192,234,57,180,150,246,104,201,182,31,67,27,80,108,157,185,36,233,142,96,43,124,93,188,11,163,20,118,28,198,248,106,137,123,115,64,4,30,253,61,74,170,242,152,63,51,255,196,140,74,197,246,245,37,127,219,204,235,21,131,214,140,8,171,233,8,41,111,158,132,176,111,167,190,250,66,158,238,54,2,200,209,136,237,110,117,113,162,16,131,246,78,255,61,28,144,60,13,220,43,7,15,127,156,202,41,199,67,241,144,162,202,243,177,90,70,209,243,40,12,201,226,75,243,218,21,174,127,178,31,205,133,54,215,212,87,213,206,63,120,140,176,248,0,126,229,115,166,133,205,138,237,161,144,107,181,61,48,233,134,96,234,80,160,239,114,211,205,199,96,175,137,29,79,15,33,144,61,150,44,50,94,198,21,199,86,145,199,244,105,166,103,199,22,130,172,156,98,144,114,234,189,140,234,209,146,173,26,113,195,200,143,180,177,210,144,64,1,1,58,20,183,59,78,135,143,251,162,104,167,0,189,235,107,91,176,40,134,11,215,246,215,17,65,215,27,156,60,169,218,106,29,230,8,119,173,171,178,216,125,123,205,230,126,38,255,158,178,129,74,137,242,9,23,244,114,5,238,229,141,142,71,217,8,88,245,136,85,240,201,81,249,173,241,24,91,125,247,93,28,218,45,101,38,92,164,200,1,165,188,20,88,180,195,34,51,96,225,147,188,219,238,6,155,182,132,17,109,17,29,62,78,88,78,23,141,120,132,5,36,237,20,188,208,144,173,231,50,239,70,161,27,180,237,24,109,81,237,166,217,150,27,154,148,8,89,42,105,78,234,23,39,226,41,100,55,78,217,238,242,89,45,81,144,254,80,242,227,86,33,45,254,171,69,53,107,106,62,123,171,130,33,107,4,135,25,159,133,251,3,117,195,23,61,159,244,181,207,244,103,26,18,45,214,138,212,117,41,159,115,26,251,45,190,19,178,127,224,223,219,250,240,39,70,1,201,190,152,243,17,87,227,44,177,192,100,175,126,83,220,190,59,160,23,243,242,253,139,127,160,48,36,151,171,37,73,94,5,149,167,186,86,190,55,146,74,124,223,113,121,101,74,246,97,6,179,132,239,244,140,17,219,179,140,12,206,218,167,60,201,66,19,103,19,161,103,25,206,125,162,138,200,123,210,255,206,158,152,26,221,29,85,90,31,212,175,185,230,98,141,199,144,9,72,116,155,24,250,171,133,71,187,132,43,229,200,38,83,195,121,89,71,221,196,86,231,1,11,31,66,250,0,204,185,39,47,180,112,138,237,230,144,237,27,139,209,62,99,208,114,91,143,252,206,130,54,124,184,163,76,49,220,133,223,152,123,65,75,129,248,35,122,244,124,186,105,13,106,237,136,252,19,150,107,179,143,181,68,69,4,220,96,122,10,126,45,139,251,134,131,214,215,150,239,155,40,99,168,62,7,255,184,154,70,43,155,85,134,134,29,29,178,148,237,47,32,65,135,100,100,101,165,30,246,18,174,61,221,90,223,136,255,7,8,230,122,158,173,36,33,163,13,164,12,128,224,181,8,87,221,186,48,128,123,101,231,60,18,206,131,39,227,41,100,36,56,107,233,118,42,130,161,248,169,14,208,229,150,24,247,33,144,219,19,246,98,204,59,18,160,195,207,4,12,198,50,247,76,12,133,2,51,188,238,195,163,243,145,34,27,161,195,136,111,236,88,98,113,45,251,197,141,230,165,84,111,175,65,8,166,45,210,150,184,77,235,87,28,3,13,123,117,157,49,219,254,108,51,91,90,134,111,202,107,71,70,136,16,0,142,3,194,200,27,207,139,31,41,192,55,248,230,101,71,215,181,224,22,234,194,137,20,29,113,168,45,144,144,171,45,77,103,181,199,117,219,200,150,46,20,87,141,117,221,245,121,131,132,108,39,103,52,231,141,64,240,181,163,223,195,194,58,30,240,244,126,137,210,148,26,233,149,223,235,106,84,40,236,199,174,130,55,7,101,35,36,135,225,20,210,157,108,239,91,99,217,142,132,84,173,5,32,105,65,27,7,160,108,135,93,204,173,244,232,148,31,160,48,102,63,205,63,115,235,81,0,147,100,196,57,233,110,251,117,4,133,136,168,56,218,38,141,171,125,135,39,110,217,35,160,21,133,129,143,43,224,133,94,15,141,184,171,18,32,171,161,156,113,22,47,10,189,184,155,249,175,104,19,164,23,231,174,103,57,235,254,51,237,74,42,69,52,107,82,211,36,39,147,64,209,89,85,14,208,55,238,211,159,77,205,151,151,45,33,36,137,108,66,154,22,9,151,235,84,87,204,30,14,172,167,185,170,114,206,253,31,11,133,199,61,57,73,97,128,142,225,141,20,200,168,252,214,160,140,70,124,96,144,228,238,50,10,129,136,215,190,141,170,221,212,59,27,3,101,254,142,158,32,185,90,40,144,35,226,188,234,201,199,122,199,110,12,35,117,45,225,36,44,104,44,31,89,183,120,115,7,139,13,227,137,7,89,126,201,152,234,192,76,6,49,103,20,243,28,3,248,23,163,167,35,101,147,130,46,85,251,39,231,195,235,30,204,32,250,52,27,68,45,140,221,161,23,1,6,171,14,124,115,41,10,59,250,35,123,123,235,61,61,166,212,223,31,95,240,133,62,7,145,22,141,199,164,231,146,166,71,238,10,177,71,203,142,144,133,202,49,246,46,242,133,156,32,255,150,113,41,89,208,244,202,82,193,165,176,240,134,244,75,97,235,47,86,12,29,85,83,3,150,66,57,45,231,241,116,154,237,219,95,111,116,86,139,67,23,212,201,73,138,217,42,246,252,33,10,115,240,75,36,238,243,204,151,3,169,248,67,212,186,158,25,28,70,70,166,48,204,107,143,14,74,177,146,21,34,225,65,205,62,59,141,178,117,21,246,164,139,203,136,189,119,225,4,147,171,170,22,167,191,71,217,202,11,215,194,57,189,67,59,12,226,210,63,84,116,190,121,51,147,43,16,235,70,95,241,92,37,106,85,186,134,49,133,200,178,39,111,208,55,113,147,65,35,225,196,22,0,8,7,12,204,69,193,152,89,135,75,181,215,4,156,10,190,73,75,141,121,198,244,244,234,126,55,54,222,22,48,154,33,56,109,204,19,252,3,84,210,255,9,231,233,148,129,205,176,27,203,0,245,84,220,156,123,136,139,209,76,250,245,210,24,92,20,101,204,113,247,152,231,7,28,172,103,71,128,107,204,99,234,185,160,89,243,182,96,108,220,196,20,158,54,66,230,155,187,124,179,75,111,142,46,110,11,179,91,219,227,81,137,211,33,39,128,139,22,84,110,57,215,13,205,62,192,144,112,207,146,9,50,82,53,167,48,85,47,118,109,234,20,86,94,147,30,111,2,202,52,139,204,177,103,239,169,32,26,219,215,158,61,145,80,24,216,19,110,200,186,118,91,10,111,24,137,239,66,221,76,219,155,125,222,23,201,122,73,227,145,205,169,179,211,241,164,16,83,59,193,22,135,201,128,64,88,239,0,128,178,173,2,108,205,242,150,47,175,97,51,208,77,116,122,65,14,62,198,84,196,248,193,65,96,40,228,184,246,246,245,155,31,115,230,129,14,93,188,160,167,89,5,61,170,41,202,136,87,252,42,59,11,116,91,195,30,218,128,251,12,182,33,107,198,22,182,236,220,215,54,24,183,34,220,252,249,151,138,85,44,210,131,238,87,207,126,227,46,0,229,64,86,140,121,103,192,97,231,23,177,53,99,222,35,51,115,11,161,226,178,249,112,159,45,208,216,189,33,238,56,110,236,68,178,143,156,177,237,221,176,207,50,205,55,243,208,89,45,230,80,130,196,218,7,97,155,8,137,126,250,173,2,68,157,120,172,153,115,226,91,68,222,105,80,179,28,161,224,3,25,84,81,102,202,5,162,156,64,151,40,112,9,229,120,189,149,44,179,154,164,210,92,120,227,162,86,132,104,6,144,230,85,96,158,253,245,129,47,115,159,73,202,109,193,169,119,131,64,101,219,78,20,228,25,9,197,195,188,5,179,52,96,151,27,151,54,60,231,145,62,148,185,0,248,3,183,143,101,94,0,83,149,128,147,11,37,192,82,47,57,185,5,38,215,218,62,196,151,107,208,237,59,247,209,189,186,19,15,196,167,116,227,10,6,22,175,173,237,90,107,71,106,245,113,176,246,207,112,174,101,250,239,85,81,182,137,88,117,4,80,123,226,134,152,191,235,197,181,202,230,227,168,42,238,142,137,107,175,134,251,243,164,61,102,53,184,211,86,222,239,167,75,235,44,140,215,42,245,213,13,41,106,216,19,154,9,55,91,106,9,253,230,90,61,95,10,139,63,50,120,99,63,131,60,197,64,235,119,49,178,35,203,58,253,243,44,22,97,202,124,17,92,18,121,98,103,116,65,213,39,235,202,215,202,201,95,49,100,130,248,68,9,46,91,190,236,159,97,0,122,183,247,246,248,82,66,172,177,205,92,229,38,251,64,174,163,183,220,108,225,158,87,205,91,84,135,91,185,16,40,57,125,35,98,160,119,49,169,18,100,235,212,67,148,151,222,42,31,176,244,16,175,89,9,50,127,220,114,145,100,224,246,98,208,211,217,99,196,160,127,189,19,136,31,0,235,65,246,11,179,17,25,167,177,179,153,198,16,161,202,111,90,103,171,159,74,87,216,117,196,104,43,44,120,78,44,140,155,58,102,198,37,28,149,11,31,144,5,247,139,110,109,244,104,239,234,74,230,15,61,75,24,28,111,186,217,52,80,114,101,166,31,71,202,94,159,126,226,55,86,228,83,35,238,169,85,182,171,188,91,46,148,140,115,43,143,192,185,157,109,38,85,107,185,68,216,46,250,121,78,204,251,150,213,216,230,122,152,241,68,17,158,55,155,143,149,1,252,87,2,19,111,185,191,119,75,140,51,182,172,106,235,44,195,220,250,233,195,212,105,167,111,94,48,60,76,43,32,72,3,118,131,62,187,200,212,240,38,27,175,153,159,94,38,168,149,113,151,42,208,147,174,191,131,102,110,49,197,127,118,188,45,38,104,112,140,70,9,174,113,149,55,214,128,95,223,244,231,42,63,164,59,131,143,119,62,76,107,27,104,64,183,180,91,101,228,21,49,154,11,125,33,109,200,184,184,95,224,222,100,253,82,151,51,190,164,179,176,181,154,152,182,241,155,219,234,52,7,47,111,236,163,105,125,175,255,12,190,73,183,231,44,9,99,64,93,149,80,73,96,232,229,162,166,101,158,87,174,127,127,1,86,40,12,196,216,74,45,168,249,94,238,88,49,253,152,167,123,241,215,144,215,156,188,188,177,123,87,168,14,165,50,225,52,12,116,67,121,138,66,70,201,50,251,137,169,7,103,49,83,75,49,205,240,104,204,235,127,27,244,231,197,105,104,67,118,212,213,221,147,15,157,176,108,188,86,52,4,223,48,23,125,230,22,184,117,250,242,16,111,128,226,2,237,205,215,215,53,242,223,89,77,38,53,164,103,162,17,185,204,191,30,213,13,8,208,137,157,60,123,200,214,13,104,101,216,152,186,7,38,88,151,230,53,50,35,114,5,105,232,191,190,9,232,103,238,158,123,152,144,30,178,61,118,21,36,197,36,248,43,75,238,10,163,91,210,190,45,121,248,204,88,85,51,117,49,248,182,231,78,230,47,114,211,97,182,226,168,230,135,42,244,11,140,71,156,127,131,253,212,168,105,148,50,255,34,55,149,162,169,67,106,79,64,6,70,221,127,61,22,65,195,14,124,118,61,36,132,43,42,142,36,15,98,191,12,57,96,236,9,140,165,163,167,207,252,67,178,145,247,30,53,208,34,137,227,75,151,146,210,175,177,22,180,108,82,72,1,217,194,75,24,238,234,81,230,165,3,139,16,160,161,13,81,235,142,54,56,114,232,151,122,211,229,113,156,232,70,77,60,63,86,46,162,44,67,203,172,170,173,120,155,133,251,222,59,43,231,140,69,248,237,140,129,169,222,51,191,30,100,163,165,167,207,236,106,237,101,57,52,56,72,113,28,147,107,216,51,244,243,63,170,25,76,116,62,41,205,133,31,191,136,154,193,240,191,254,87,177,49,117,143,134,54,164,245,47,197,70,153,64,167,236,126,166,210,118,109,110,99,159,103,82,63,191,249,116,113,192,147,237,12,141,171,114,175,173,152,95,38,158,255,189,16,244,244,153,127,137,221,106,164,118,167,225,107,243,99,98,44,129,174,63,169,77,203,3,20,132,100,205,1,98,11,44,154,34,173,191,187,144,103,216,206,152,116,252,69,109,234,112,145,217,46,92,255,234,51,45,140,145,242,146,10,85,96,47,221,199,185,244,75,145,234,46,249,43,182,129,189,9,73,59,63,225,127,2,2,245,244,105,33,92,137,121,135,192,128,204,180,162,103,30,66,147,216,251,153,167,158,254,236,194,97,184,124,89,175,79,70,105,161,41,152,254,152,68,45,255,1,189,179,162,52,45,61,125,92,58,79,46,221,161,195,5,23,198,144,208,238,66,244,141,134,200,142,138,87,170,207,168,104,158,51,122,154,116,141,42,8,232,159,72,186,145,232,48,181,165,208,247,19,160,121,185,140,74,255,115,92,149,87,238,225,94,254,118,218,155,50,170,19,48,193,11,189,26,97,80,122,222,128,0,5,62,146,106,43,91,246,75,27,168,52,140,234,0,71,135,164,226,15,105,253,139,196,44,139,102,231,35,196,144,233,37,179,211,98,163,22,45,179,98,61,50,61,102,94,245,93,120,122,254,51,196,1,99,75,171,112,189,27,177,180,66,148,112,24,130,24,23,192,68,59,244,201,253,185,183,119,133,245,3,224,190,177,178,126,185,48,43,164,117,182,89,88,169,124,36,192,248,0,54,170,17,16,160,211,194,21,187,120,8,100,112,213,152,26,59,217,171,180,240,41,120,246,167,94,163,170,33,111,100,106,111,152,173,53,55,134,251,52,248,209,79,40,45,111,116,44,21,117,90,70,66,98,235,161,201,229,165,78,60,241,252,60,208,149,238,96,49,5,150,129,220,234,67,50,39,85,254,253,49,176,75,138,159,46,171,242,255,230,2,80,204,65,72,156,121,243,226,240,1,28,67,111,181,20,24,57,43,165,221,177,63,151,173,2,93,185,58,58,42,18,5,40,163,172,240,114,221,55,106,65,233,239,135,255,133,83,103,50,243,242,26,132,255,9,167,222,80,172,111,14,116,30,190,53,48,20,28,163,26,78,69,67,159,193,63,153,221,87,112,233,39,107,202,194,232,129,118,35,175,116,96,96,75,223,91,134,67,21,114,116,117,64,214,139,178,113,45,187,8,117,146,114,42,153,158,183,75,79,17,92,56,68,17,189,20,59,26,111,157,28,243,91,6,57,186,128,138,58,237,225,31,50,200,2,34,169,167,180,0,39,47,8,196,46,201,255,132,83,155,83,3,149,84,1,177,255,168,84,123,77,253,22,31,222,16,167,206,122,137,5,45,55,245,29,154,177,171,19,52,134,148,118,31,219,152,73,227,137,57,243,168,19,204,138,188,116,212,237,9,70,185,121,109,2,13,245,79,130,12,181,190,167,100,69,254,122,88,53,32,128,121,235,48,159,217,243,227,159,12,175,229,177,251,145,78,255,82,65,118,97,48,216,251,144,144,12,27,174,148,212,254,143,10,114,215,28,29,61,61,129,120,105,138,230,176,52,144,69,96,30,116,218,162,140,215,235,42,187,30,254,227,107,110,26,250,88,101,69,254,16,19,112,225,205,67,124,102,172,188,188,159,10,15,151,163,214,52,68,250,180,79,7,124,102,231,143,135,60,153,246,243,84,59,123,26,236,201,246,219,214,99,245,173,172,164,255,86,65,142,11,64,92,46,218,236,18,62,187,187,63,206,147,78,244,146,222,183,203,173,2,42,122,215,147,29,170,165,20,36,126,185,13,122,223,250,199,63,246,50,29,178,254,75,52,59,100,41,16,141,27,77,163,216,79,84,105,30,172,227,22,164,130,146,89,97,232,50,35,240,59,90,95,206,166,162,78,123,252,151,10,114,121,64,221,134,171,202,194,6,88,243,19,11,45,179,170,185,98,79,150,208,25,131,220,12,78,230,188,135,13,197,31,240,255,210,133,75,211,189,189,94,148,244,39,93,184,131,16,179,204,46,27,187,26,50,189,236,34,195,177,95,33,242,12,191,205,237,52,90,224,37,214,130,199,105,51,79,14,226,68,21,29,61,125,220,95,104,106,11,218,143,95,120,41,99,91,98,205,131,63,209,162,209,222,63,57,78,143,31,124,88,205,126,24,253,63,156,28,182,204,139,209,145,153,56,226,198,240,83,56,187,254,253,133,7,21,149,27,10,130,36,228,49,220,111,58,179,203,153,84,212,105,122,127,65,141,33,212,94,238,70,38,183,106,32,2,145,23,2,20,171,105,54,249,114,221,99,157,255,93,177,119,251,129,44,87,34,247,240,101,153,11,189,129,236,149,87,241,204,214,150,169,146,31,84,131,168,104,132,24,28,4,108,223,90,222,104,96,82,155,178,18,26,63,96,11,231,101,161,166,81,122,254,23,91,56,231,188,142,156,42,8,174,93,156,126,67,101,114,63,58,118,153,165,58,1,94,237,36,105,120,196,50,99,184,205,38,206,158,251,133,164,75,133,51,14,34,130,156,15,243,18,69,39,40,246,29,11,158,223,80,47,28,203,21,167,161,255,32,100,5,136,106,137,100,238,230,60,58,248,251,215,196,238,111,109,127,177,184,186,210,250,131,16,117,91,69,85,211,191,30,227,162,19,134,49,219,210,31,151,56,47,178,11,169,19,214,217,252,205,102,38,196,200,204,172,246,7,155,153,226,107,26,88,245,173,43,209,105,161,33,191,198,86,211,95,118,181,188,231,109,166,9,147,242,172,226,251,181,62,1,138,247,246,39,233,47,44,245,50,131,193,149,51,25,110,24,86,38,39,227,151,158,244,188,209,41,1,65,23,36,95,95,111,24,84,237,163,4,169,254,7,75,45,68,207,204,172,246,23,150,154,46,176,6,174,159,159,85,246,179,49,192,147,189,56,245,89,104,7,59,171,154,107,27,92,69,224,63,100,102,196,125,227,249,139,204,204,139,166,79,171,16,240,48,17,33,89,132,99,118,251,249,205,2,86,212,235,43,247,222,89,249,10,52,240,158,145,146,255,245,92,238,254,91,255,234,18,122,167,152,121,103,2,98,44,40,88,11,27,101,219,127,1,152,26,170,231,93,161,112,191,155,63,193,40,246,55,207,118,171,208,213,226,164,190,247,135,155,7,120,187,212,120,191,178,101,91,49,39,195,10,95,14,70,81,209,228,50,134,116,170,104,158,123,51,108,244,189,141,38,247,55,45,168,170,106,64,128,142,210,95,92,102,52,28,39,74,221,2,140,77,238,228,76,76,48,151,217,181,63,190,97,247,245,11,246,154,85,61,21,106,169,180,109,22,63,225,135,189,178,245,61,12,48,139,63,198,116,126,41,254,254,227,150,61,40,200,255,26,100,211,121,107,115,196,109,192,98,184,43,237,142,133,202,49,214,251,189,105,43,118,129,12,151,47,119,59,150,164,70,210,30,81,122,201,99,145,138,226,120,247,43,204,22,235,208,109,195,123,25,227,16,31,15,189,123,123,155,110,207,211,221,16,139,211,192,191,192,3,128,155,52,98,171,159,185,221,60,27,159,158,92,167,60,29,41,163,17,100,160,105,90,102,4,109,7,113,75,202,157,51,174,182,137,146,151,60,191,88,214,57,221,28,213,185,120,67,14,57,32,130,172,233,182,71,190,97,20,201,15,8,13,218,224,123,103,61,153,244,76,199,212,205,233,128,12,52,0,58,20,122,242,48,74,189,251,116,177,66,135,90,147,223,222,233,112,122,11,175,62,67,215,146,38,14,143,23,39,77,191,158,180,116,126,228,155,92,11,176,238,188,243,244,132,251,139,161,249,179,153,166,214,45,23,71,219,196,49,163,112,220,115,231,218,168,174,48,115,192,76,254,246,43,171,18,97,14,218,165,99,201,35,213,118,46,125,206,195,121,227,184,68,75,72,114,57,218,133,194,247,98,164,54,21,210,72,230,121,242,227,21,75,212,220,39,218,61,82,182,175,142,55,48,203,144,52,78,206,85,87,143,26,254,181,111,116,189,217,143,87,226,168,83,3,135,120,90,234,105,152,191,12,48,171,229,164,175,167,71,41,60,222,175,45,236,90,69,252,191,131,2,143,97,183,191,166,132,247,54,57,246,135,239,238,78,129,53,73,198,216,186,194,218,238,114,97,42,131,17,125,47,30,82,106,187,172,172,236,114,43,99,196,251,55,181,149,237,41,18,35,19,140,79,206,134,190,119,106,10,73,198,215,172,107,185,112,34,95,159,238,138,117,55,164,107,135,16,201,88,166,103,236,117,178,163,128,132,231,224,95,33,193,42,133,246,12,223,77,109,231,164,67,234,183,138,64,142,21,158,36,179,59,57,128,129,180,176,55,69,245,207,240,83,200,252,178,218,85,89,200,91,83,128,122,138,113,174,97,179,87,5,72,59,153,143,107,176,217,73,7,46,253,32,68,199,65,28,46,128,180,130,86,19,225,3,22,187,97,107,211,14,153,68,241,23,231,118,16,138,155,193,61,76,48,59,191,9,239,64,82,23,129,156,249,250,183,139,109,168,6,176,40,201,79,93,184,118,184,33,133,89,231,209,39,229,240,140,222,206,5,44,248,27,192,107,213,233,235,203,163,173,206,149,223,63,187,230,102,198,127,229,186,121,62,183,154,154,231,200,216,105,117,209,111,226,92,50,180,162,31,203,119,77,169,12,49,159,159,26,78,20,93,92,77,231,217,185,91,248,241,238,206,217,147,141,119,144,32,175,51,66,179,186,163,83,47,196,113,146,99,27,49,70,79,113,39,232,130,54,106,91,186,248,234,190,63,229,222,244,27,122,56,168,77,251,49,42,142,180,52,127,215,140,251,123,234,135,225,196,95,171,147,113,81,81,241,114,225,102,86,197,33,231,122,171,104,214,144,106,22,147,143,6,58,135,191,27,245,236,137,112,157,137,51,46,226,193,161,144,74,133,123,54,249,117,96,248,213,12,44,182,239,101,250,99,165,128,182,162,170,55,178,63,192,13,93,147,37,20,242,46,186,77,12,93,128,44,123,4,5,160,2,20,4,68,121,207,226,155,163,208,190,173,255,242,242,113,132,80,81,167,209,165,169,29,38,52,220,120,16,184,221,228,3,116,206,96,2,217,187,89,154,149,232,163,140,40,41,113,169,175,164,124,38,160,40,200,246,247,176,49,254,40,185,169,15,253,237,59,88,36,94,114,220,215,6,213,163,37,219,94,62,237,187,246,163,5,87,132,198,61,166,108,55,3,71,247,171,99,35,115,23,9,41,191,13,135,173,161,78,88,127,97,105,171,240,152,229,215,96,38,133,121,28,26,175,176,213,117,135,169,234,46,167,69,175,75,121,159,81,221,87,187,244,64,25,153,240,27,193,246,44,239,159,170,97,54,135,193,184,205,17,55,31,159,241,39,217,61,50,210,121,141,21,35,174,216,138,65,235,23,241,3,215,160,59,158,62,205,60,62,149,217,8,216,112,237,70,183,58,142,48,0,218,162,46,47,239,55,107,3,181,13,131,145,99,107,247,121,222,202,67,42,208,115,41,144,209,79,207,89,199,246,11,113,75,40,193,16,181,209,173,190,43,231,61,226,130,170,89,210,17,196,4,169,159,249,102,139,107,218,212,183,148,26,243,140,129,108,141,249,16,174,79,120,146,68,138,42,173,201,117,51,140,94,27,187,133,212,153,51,199,191,215,23,162,198,23,179,52,19,57,58,62,240,246,125,121,197,63,22,111,238,186,240,240,9,137,48,128,62,206,122,169,146,180,57,210,233,82,214,46,169,16,177,184,218,9,39,247,144,72,120,248,150,165,120,221,246,123,238,171,86,1,230,30,237,18,36,104,89,243,121,72,101,224,17,52,249,94,209,227,44,173,228,69,108,129,156,17,8,234,5,138,220,115,67,47,75,74,193,246,124,179,37,74,60,39,252,113,30,8,143,59,97,167,218,145,247,7,82,33,26,29,47,174,84,188,29,113,72,143,24,165,62,118,110,50,222,212,238,157,156,230,52,99,28,11,94,221,2,57,142,173,27,125,24,163,57,92,141,228,94,23,105,219,213,138,96,199,22,243,62,174,177,104,213,43,145,92,252,182,189,222,255,89,72,224,119,167,24,236,66,23,129,2,221,140,97,156,187,126,40,242,41,90,157,167,243,7,86,102,125,86,203,206,214,111,224,6,80,149,61,16,44,9,70,9,38,167,48,88,250,207,136,128,86,147,87,9,139,124,57,197,141,167,100,43,247,131,80,4,151,68,30,249,209,166,22,191,78,164,44,206,119,11,247,213,103,202,249,225,19,25,77,237,173,116,0,233,203,126,200,177,160,1,236,135,141,9,160,235,104,165,92,173,229,222,146,61,208,163,237,10,42,73,118,234,25,255,26,137,35,125,197,75,63,12,54,186,38,185,137,246,44,236,32,173,70,193,61,65,228,181,55,99,5,166,101,214,165,75,85,83,145,64,242,45,159,14,233,57,207,227,6,14,108,237,94,3,22,115,193,116,4,193,208,29,145,98,247,189,213,102,52,128,188,18,230,250,234,46,71,174,182,53,158,205,159,75,214,187,32,113,251,199,39,49,130,241,84,143,54,112,172,253,237,181,198,43,85,15,147,62,118,138,13,10,179,97,79,35,226,54,127,106,118,130,145,181,27,221,21,58,228,149,239,141,208,84,177,37,44,185,36,139,213,178,28,2,72,242,91,204,85,168,100,245,0,254,136,190,51,74,218,154,192,71,202,111,154,0,206,197,98,104,244,24,232,133,28,60,86,26,142,161,141,45,97,85,43,250,118,199,167,106,96,241,207,131,36,128,20,98,39,244,145,248,108,238,28,30,182,133,86,0,245,129,78,230,61,102,251,160,79,181,80,187,53,222,22,179,120,222,196,41,55,115,44,152,73,97,50,88,227,231,69,240,197,55,247,95,63,15,121,216,77,92,141,130,47,181,179,77,58,142,122,130,176,50,236,33,225,241,79,184,68,224,42,104,36,156,216,6,170,168,65,174,127,184,232,207,178,221,120,51,230,98,129,229,150,161,176,255,83,79,68,116,250,239,93,117,130,54,28,196,131,117,27,232,32,28,38,119,175,175,161,207,1,140,250,201,230,47,174,106,60,100,76,38,27,185,239,118,14,12,111,149,135,5,212,143,210,223,188,160,202,239,224,90,166,69,22,75,244,90,17,193,96,72,203,110,174,101,237,146,91,252,178,92,61,57,119,40,197,141,167,202,88,174,240,157,97,107,219,18,28,230,142,240,36,206,234,170,84,245,104,201,22,226,12,34,114,136,27,217,192,229,207,22,215,58,240,91,115,236,122,14,108,45,103,237,83,88,22,109,118,19,11,89,12,64,141,121,248,237,9,123,124,237,88,193,16,199,9,189,167,166,89,223,115,23,197,106,38,105,124,190,94,107,102,83,59,46,238,86,71,180,3,36,205,63,230,205,167,36,73,123,136,174,60,42,66,175,124,100,68,11,16,145,148,29,113,212,116,164,236,206,171,219,119,41,69,51,82,73,92,178,153,203,83,214,93,179,17,82,227,143,194,0,48,223,43,105,113,192,47,65,186,24,98,187,219,48,55,15,91,231,75,47,212,28,179,232,203,99,102,64,159,155,123,53,114,235,95,111,224,126,184,33,150,242,20,6,207,236,77,123,57,101,180,183,121,53,240,206,128,11,31,80,158,128,33,190,27,37,42,99,24,248,194,196,152,185,91,109,95,77,87,1,153,33,107,185,110,23,135,35,41,93,189,156,114,117,58,25,53,150,2,193,45,124,126,121,214,166,33,85,157,132,123,164,242,148,205,137,194,105,233,219,32,100,210,91,185,80,55,238,48,29,177,39,255,29,217,34,38,38,103,47,84,232,31,161,58,236,92,214,158,48,62,16,65,140,195,213,246,129,206,195,206,230,119,27,22,237,50,100,154,204,225,238,222,58,104,130,124,66,123,134,207,32,165,34,227,210,97,4,153,224,36,68,58,238,131,194,253,174,241,22,210,13,195,165,156,78,228,120,30,236,219,93,78,162,80,219,26,116,136,81,51,177,162,77,12,189,237,195,192,225,79,194,130,58,179,25,244,125,200,167,213,197,112,117,222,243,3,123,189,142,112,226,58,98,44,169,35,74,110,198,220,77,203,103,130,188,137,194,246,167,127,51,176,54,190,255,228,238,188,73,199,218,132,43,122,121,84,176,48,134,52,12,70,122,197,80,8,226,19,12,78,207,215,59,100,59,163,142,154,218,68,72,248,171,69,80,233,102,67,71,149,192,134,163,225,34,17,143,60,20,246,190,104,190,91,243,59,243,232,117,121,182,242,17,9,239,31,59,126,35,171,183,174,222,189,205,112,17,112,211,33,26,64,72,99,17,197,215,82,96,48,193,156,151,109,176,85,70,159,169,231,130,253,17,12,223,232,121,120,184,175,89,223,101,100,246,239,46,68,227,170,93,187,51,238,105,17,224,246,89,154,99,118,199,12,201,76,157,219,105,76,90,162,152,189,53,114,169,68,83,210,102,238,222,148,228,163,122,69,4,229,235,187,27,99,152,235,193,83,238,181,98,227,89,238,33,209,202,103,107,175,17,34,246,114,214,72,171,85,115,59,11,56,174,78,55,130,37,241,51,3,182,60,139,34,59,253,242,198,226,235,124,57,205,218,108,93,237,4,63,77,243,156,160,228,239,215,68,96,9,18,240,8,50,95,47,208,210,190,102,34,182,57,222,220,101,65,25,137,78,49,31,206,114,209,183,90,190,151,120,93,60,30,56,83,62,48,54,100,143,88,86,177,109,98,212,241,30,46,117,38,109,4,249,137,247,156,189,49,94,98,53,126,204,27,118,43,79,253,137,245,71,86,220,115,193,148,149,133,55,101,55,143,28,61,245,8,169,13,27,11,255,210,117,101,161,86,50,116,244,8,147,156,142,212,21,4,14,43,149,173,105,220,175,144,169,108,47,84,156,161,56,128,32,111,8,142,156,125,236,187,222,46,133,30,29,32,103,188,6,110,179,40,189,118,220,75,19,126,82,155,251,91,142,44,246,126,61,153,73,228,15,134,69,1,129,226,217,236,83,69,69,132,220,59,121,224,97,140,129,100,226,99,205,218,105,77,178,97,1,122,32,76,100,201,196,87,97,49,39,253,241,207,174,45,175,57,19,21,120,95,208,77,162,59,119,237,183,153,202,194,194,233,168,145,13,203,62,67,99,139,114,92,101,196,108,49,245,197,100,242,118,24,0,102,82,94,30,182,216,138,122,117,142,252,86,19,97,84,46,244,125,13,220,93,110,30,6,37,196,155,187,182,180,85,4,24,141,173,154,0,177,245,157,61,131,102,119,188,102,68,34,10,203,245,203,9,47,253,185,18,195,11,118,50,197,151,223,101,230,74,39,121,118,223,123,114,222,239,1,120,198,64,188,118,163,59,79,243,134,49,106,162,159,117,241,53,5,65,217,179,71,40,59,186,144,18,171,167,215,202,132,250,243,242,64,163,41,126,139,185,121,17,239,243,134,55,124,97,111,232,248,25,230,66,192,165,18,47,242,140,65,80,175,58,208,145,81,3,206,196,86,49,187,158,205,178,194,177,216,185,116,73,55,103,138,47,224,50,220,252,198,229,78,148,195,217,54,192,85,43,43,67,163,129,251,30,154,132,88,125,173,220,225,97,101,133,90,77,58,227,242,114,72,30,71,78,75,103,148,248,41,185,149,250,234,53,212,208,108,207,106,52,92,44,158,21,57,51,159,30,181,185,21,129,187,146,56,165,25,188,91,42,103,157,88,149,135,227,25,51,223,177,239,97,226,104,165,119,68,86,78,133,215,36,33,246,126,8,18,137,37,228,118,60,54,26,67,87,145,183,90,215,113,67,136,248,98,69,90,250,179,130,32,147,216,19,77,180,145,27,106,186,217,103,172,229,252,239,234,54,148,74,255,243,16,165,205,254,16,239,48,239,69,106,44,213,102,95,225,78,221,248,7,167,162,225,207,59,97,9,96,182,144,157,207,141,151,222,221,170,190,3,129,109,161,39,66,143,12,77,115,98,182,239,162,22,178,18,103,119,69,43,167,6,214,142,191,231,184,93,172,203,206,122,73,99,165,25,224,55,207,103,31,120,130,253,237,115,227,36,186,147,107,123,229,184,200,254,80,161,120,96,131,178,159,3,26,95,183,59,218,235,168,191,108,184,60,252,65,33,138,46,122,207,93,222,36,186,158,199,119,146,154,12,21,5,185,121,158,116,95,247,18,138,69,18,194,63,112,116,49,136,20,76,198,204,147,76,237,147,207,198,52,203,242,107,224,227,241,94,48,77,110,205,62,142,129,99,221,158,222,28,95,86,211,239,197,91,120,15,45,213,60,10,82,126,235,208,147,19,55,135,128,215,21,145,185,226,222,59,206,56,129,233,164,81,155,195,224,93,194,27,14,11,79,93,184,37,14,47,194,190,104,77,45,106,31,40,3,191,207,148,55,117,148,219,89,71,138,75,4,120,235,13,231,93,17,34,7,169,177,228,107,231,56,219,149,23,67,202,83,160,189,169,57,88,68,202,126,170,146,252,100,246,157,214,86,152,164,38,139,3,181,168,148,223,198,252,222,7,33,253,172,74,8,190,22,245,192,192,172,239,4,162,163,103,254,174,13,137,160,48,46,213,248,244,164,7,71,192,26,129,73,48,20,204,99,197,255,10,182,18,12,216,246,136,179,228,79,185,169,247,197,205,136,169,79,61,189,113,42,203,235,237,71,142,69,138,27,101,211,205,2,143,157,121,83,38,192,7,143,136,77,204,121,165,121,220,229,113,65,181,86,25,163,207,93,37,195,236,188,223,199,221,214,212,89,47,69,220,167,245,36,14,21,69,9,199,183,79,61,194,46,45,169,58,8,103,116,181,20,117,184,120,173,13,151,201,180,20,146,253,10,79,129,48,226,16,209,4,9,239,32,224,206,124,186,235,92,50,208,237,222,210,137,23,12,6,50,194,176,147,169,206,229,44,8,124,89,167,2,214,123,240,193,49,192,25,61,227,82,181,147,99,139,134,137,126,88,217,126,71,183,150,222,33,231,57,112,245,7,107,162,182,60,79,208,145,86,126,217,22,80,100,55,192,111,62,141,236,181,122,155,135,200,32,199,214,54,112,211,150,24,127,87,204,154,88,93,116,230,68,184,99,191,185,155,60,170,85,56,191,183,191,166,4,219,83,125,163,73,19,76,235,184,35,27,71,88,185,195,132,126,99,9,19,42,168,101,21,185,172,99,81,44,95,187,57,12,38,27,20,166,179,50,53,175,97,40,36,60,103,153,203,142,12,211,199,144,24,127,46,186,215,89,218,168,133,118,209,59,229,35,122,234,226,51,193,94,47,196,235,124,123,228,170,71,22,202,218,215,28,135,201,161,47,196,204,118,32,57,143,82,190,214,237,244,33,43,68,213,244,23,135,84,249,164,200,21,171,174,83,33,207,59,148,109,76,135,69,215,149,20,244,39,222,46,254,200,167,74,171,120,36,190,195,73,38,93,74,116,158,122,202,4,192,129,176,183,111,95,210,4,100,19,98,173,189,71,252,119,110,184,206,119,165,61,73,208,246,159,98,117,221,46,254,238,165,127,186,142,180,57,66,92,125,174,173,245,65,31,188,133,201,106,31,121,50,151,188,62,237,119,109,122,249,172,23,158,125,126,4,182,187,140,221,140,35,70,80,190,173,2,179,109,139,46,254,22,202,8,236,165,165,167,207,236,159,250,37,234,245,203,119,158,4,118,177,220,231,116,187,92,123,239,196,245,79,93,81,214,156,198,164,69,97,0,189,144,145,229,66,191,169,61,15,70,157,103,158,97,240,147,150,79,109,215,229,23,111,64,37,175,56,20,242,82,229,159,68,242,113,143,32,95,241,14,179,105,172,181,108,68,55,81,127,166,16,250,125,157,92,236,253,109,29,157,205,196,32,115,73,76,244,68,227,77,171,93,118,170,46,135,148,207,133,28,151,191,136,93,134,132,47,56,63,174,126,84,104,74,148,12,53,151,51,216,170,105,151,28,169,4,35,209,146,25,229,250,254,197,124,234,105,84,157,56,52,30,119,222,127,133,111,196,230,88,89,141,231,173,163,125,143,163,149,136,12,215,183,81,126,197,30,79,197,100,63,168,95,85,123,114,115,132,225,238,182,71,220,27,248,3,194,183,47,146,137,214,29,81,162,78,222,174,230,187,75,9,83,153,174,40,146,55,110,163,71,123,43,59,151,100,83,236,186,50,217,160,21,24,87,73,132,168,206,57,62,76,38,161,190,41,115,19,189,158,78,173,78,149,105,34,231,234,136,237,110,59,138,81,19,72,134,161,248,137,43,124,140,24,113,38,42,162,143,90,58,165,175,200,109,90,83,178,35,178,55,133,173,87,159,251,46,37,66,106,60,199,251,42,36,83,215,196,123,235,233,203,210,53,66,255,196,0,114,81,117,48,119,13,4,157,97,223,106,205,71,254,8,229,104,139,226,100,197,107,206,188,250,154,133,64,4,89,8,19,54,27,58,13,132,213,15,228,103,84,53,2,2,116,172,79,106,121,29,74,206,139,197,58,10,166,7,48,106,12,159,152,194,91,243,10,191,157,18,65,214,60,110,219,129,111,124,83,73,19,151,3,10,113,135,197,148,153,110,193,56,206,93,182,123,191,80,254,97,193,31,195,238,55,176,94,176,23,24,173,11,27,28,255,28,105,98,174,157,237,157,151,204,182,21,118,2,28,165,159,237,100,86,181,115,37,30,89,75,174,169,161,26,184,30,240,93,5,201,182,104,232,41,253,35,250,26,199,9,191,46,206,169,178,82,79,44,18,83,215,227,192,79,247,86,12,179,247,24,40,127,191,38,220,164,174,240,21,155,183,237,12,56,161,202,27,229,43,148,86,19,78,103,23,239,94,33,169,215,127,190,67,104,210,26,188,80,25,33,133,227,18,117,68,189,60,67,50,177,137,144,24,245,30,113,145,26,232,121,120,22,139,252,196,208,45,49,114,243,202,232,96,137,13,56,144,86,214,177,164,225,133,116,196,108,247,252,249,170,36,232,230,144,183,83,78,230,154,168,43,131,28,59,22,160,118,37,235,25,18,188,5,114,23,208,151,75,56,118,125,239,238,28,4,188,101,155,230,15,178,20,237,213,122,105,204,188,200,125,221,193,139,169,255,177,216,144,72,126,5,141,235,230,29,203,210,240,114,253,228,61,59,7,193,107,142,191,79,252,0,199,153,153,23,85,34,154,50,15,179,125,152,211,212,189,184,81,2,211,50,52,6,109,51,141,140,138,32,203,221,159,138,161,146,68,142,90,212,65,91,125,70,7,78,145,204,20,194,5,102,141,252,207,95,179,14,129,231,191,82,78,211,160,204,115,0,174,127,146,223,25,180,33,191,149,25,32,61,139,153,122,190,41,83,244,237,198,227,31,170,112,129,251,174,125,81,50,126,216,66,212,232,245,54,81,125,31,229,51,210,172,214,76,106,249,175,171,105,143,149,94,142,141,148,223,26,245,240,154,195,70,100,137,228,119,102,47,30,145,151,201,114,236,116,173,35,106,251,45,72,217,18,18,177,176,233,205,33,123,68,101,219,152,103,143,166,22,24,32,17,143,76,125,213,90,96,55,131,1,235,103,57,90,240,45,187,249,188,32,96,214,90,69,198,198,33,248,101,133,36,155,219,151,70,114,3,134,234,118,113,216,35,134,77,132,103,195,237,198,122,215,150,190,185,166,54,30,115,242,15,85,18,42,236,216,29,234,132,113,156,30,244,18,38,102,187,200,160,184,221,106,174,129,100,231,59,100,241,31,2,186,162,214,214,238,240,36,130,158,248,52,211,178,76,191,18,206,110,139,143,3,144,166,221,199,6,218,196,129,95,53,161,54,225,110,55,226,86,147,241,131,80,82,57,178,73,128,108,74,184,210,95,226,158,215,80,253,233,162,255,52,22,129,210,59,46,50,168,25,167,52,143,78,164,61,167,244,187,132,20,233,250,230,134,76,98,84,57,140,2,120,194,90,60,110,227,69,147,221,191,96,60,81,101,73,41,98,255,81,141,45,226,246,35,148,209,110,141,66,163,244,139,237,122,115,116,21,28,222,179,92,111,130,203,236,215,238,196,94,25,169,19,98,244,182,237,254,120,249,173,189,245,206,221,141,246,14,144,87,159,225,58,139,186,151,62,58,183,182,192,131,252,254,133,88,30,250,171,99,79,86,149,186,120,213,39,124,190,145,232,43,151,58,11,176,46,114,105,248,14,209,111,175,13,68,158,250,192,161,225,190,219,135,132,205,236,151,244,24,117,71,54,225,231,61,179,242,133,18,17,74,253,228,109,61,117,177,153,35,55,86,247,90,98,4,209,251,81,217,168,179,104,198,173,242,251,83,47,130,241,184,10,0,250,1,192,199,218,25,213,121,195,190,227,165,56,90,193,188,159,235,184,231,176,99,118,40,131,157,144,167,75,24,143,183,201,192,134,199,16,191,186,45,27,158,178,2,19,19,108,106,148,241,18,27,233,209,150,159,57,73,151,189,57,225,209,41,191,110,21,173,213,103,166,209,180,198,93,6,150,191,144,115,205,246,59,116,22,52,56,13,226,192,99,172,229,7,76,237,151,107,200,106,190,91,99,62,232,87,252,42,253,99,109,92,210,236,248,229,62,35,243,246,147,37,1,118,106,137,76,195,106,247,116,81,159,42,212,86,111,8,148,84,235,91,28,156,165,138,41,42,230,44,253,169,203,230,192,172,99,143,168,198,235,99,55,214,189,250,239,84,176,171,0,63,65,35,58,33,75,37,42,231,67,186,114,81,19,48,52,224,221,251,87,98,139,86,3,27,14,200,193,29,145,4,73,151,224,147,146,143,80,163,143,213,83,154,226,205,93,23,140,206,212,5,213,50,133,46,174,166,6,159,242,156,254,28,225,1,11,151,132,32,237,233,12,78,149,235,170,200,226,107,60,96,69,253,27,103,107,6,39,31,185,246,3,72,119,204,231,102,123,245,181,9,11,110,149,223,143,162,150,237,21,166,199,63,232,222,129,137,120,78,114,200,146,11,129,178,63,94,201,119,164,200,183,45,127,232,209,194,161,48,164,66,200,124,90,216,168,244,92,210,116,29,153,128,156,115,140,245,235,122,31,188,166,216,150,122,59,120,113,17,104,243,249,196,22,134,178,139,193,145,182,38,182,176,231,28,123,59,208,248,58,176,163,83,242,108,201,222,149,138,193,143,133,229,179,102,79,198,243,40,46,168,8,159,97,248,114,249,64,181,10,0,218,27,1,0,142,39,251,175,181,184,86,74,215,218,83,151,85,183,151,13,221,137,47,87,46,241,95,139,65,108,220,99,163,116,61,152,137,137,250,146,43,91,69,72,28,196,113,241,101,92,169,115,131,42,15,240,11,99,238,48,105,86,80,7,31,53,227,253,178,86,1,247,171,222,89,4,161,5,17,254,221,237,9,18,109,22,214,212,53,47,196,235,6,17,236,109,3,137,14,179,76,159,48,221,208,205,246,54,157,25,47,129,244,92,224,132,189,53,147,218,52,107,136,92,56,161,23,106,33,74,137,148,197,121,238,46,163,16,144,189,213,102,146,124,33,246,155,159,233,106,93,29,161,223,220,166,168,69,78,189,61,138,159,81,183,252,225,98,97,248,231,93,225,92,181,95,8,9,106,218,211,44,86,173,149,255,252,73,22,195,76,167,116,43,71,82,233,2,78,124,189,76,166,17,42,152,141,31,61,57,150,236,149,188,114,69,24,190,84,210,44,163,105,60,123,68,209,244,216,46,30,182,37,187,133,158,32,141,159,44,141,132,187,152,177,94,194,62,70,182,221,213,127,103,241,168,129,14,87,31,124,106,109,151,253,198,187,235,182,121,220,55,236,94,82,178,89,56,241,24,138,229,121,117,98,111,182,66,28,2,233,56,23,185,243,89,23,87,179,222,209,182,5,53,88,246,180,71,120,197,203,182,145,251,194,142,124,148,149,223,49,114,57,97,16,242,130,113,198,132,4,242,91,184,184,53,35,14,31,154,203,207,8,53,137,180,213,117,15,131,147,30,101,127,83,27,102,251,17,158,56,207,102,181,61,43,133,89,136,148,158,53,97,60,247,16,44,96,26,100,66,177,38,6,31,99,218,164,14,93,118,46,188,100,186,251,88,148,85,83,27,69,33,239,238,58,163,99,1,140,61,30,14,197,254,157,245,129,71,198,12,141,45,102,130,149,202,236,28,229,223,119,69,54,159,243,120,169,191,226,210,163,41,213,222,83,177,174,100,47,165,231,5,73,89,116,59,238,153,146,245,0,91,16,156,159,92,245,237,41,119,21,26,87,35,50,177,218,213,200,84,69,80,70,218,83,103,156,186,177,110,191,107,83,226,111,171,127,162,223,0,202,197,254,254,33,185,33,27,9,41,30,187,18,249,163,101,237,149,114,154,251,26,201,207,125,212,189,153,184,235,247,145,150,78,178,60,123,49,56,4,83,14,129,68,75,131,219,6,2,214,240,221,16,135,111,53,247,20,111,86,217,190,206,145,138,59,80,20,165,11,220,30,75,103,91,84,227,57,124,216,85,79,219,123,188,168,99,106,138,62,176,180,209,65,64,123,240,38,157,193,110,121,31,253,217,136,121,83,219,62,67,127,38,255,66,214,186,69,217,175,54,217,85,155,187,186,124,39,77,1,143,234,169,113,207,26,153,196,55,198,7,90,7,158,189,197,201,36,75,92,176,187,195,248,101,187,173,47,152,93,79,20,116,183,73,247,110,211,218,139,6,58,184,180,176,128,172,123,110,102,252,7,137,167,78,84,17,51,248,98,210,41,220,238,4,165,14,168,201,212,248,244,36,99,122,40,87,107,84,67,106,156,177,229,16,49,247,187,168,75,1,188,100,175,115,240,114,22,165,110,69,9,53,127,225,133,221,147,254,69,36,79,196,76,24,180,220,44,111,112,184,79,102,63,41,95,218,113,114,188,185,166,140,61,94,75,218,28,145,129,22,153,151,144,18,227,38,174,7,115,165,95,212,13,200,247,62,217,228,17,9,36,251,162,6,163,175,186,164,106,167,121,110,130,42,143,229,187,14,136,227,18,4,163,76,217,218,195,137,126,155,111,47,3,213,93,219,219,196,4,142,243,67,63,240,139,96,124,35,131,192,198,247,221,67,53,117,29,182,188,220,203,156,189,180,155,119,171,191,97,222,126,216,64,22,174,165,145,61,80,98,137,161,65,152,127,81,41,90,212,52,74,51,127,201,59,161,104,22,167,190,170,48,123,38,150,158,59,198,105,250,240,85,117,125,144,211,76,246,29,112,186,95,194,212,210,243,102,196,35,21,30,175,88,115,235,231,23,23,59,158,61,229,250,230,49,117,92,80,146,39,243,189,227,199,155,18,9,52,130,77,145,148,183,223,2,34,79,1,35,18,179,180,68,92,219,196,208,5,104,60,121,119,172,33,236,156,117,186,164,243,98,197,199,138,110,53,17,233,66,82,250,55,25,98,60,193,156,179,109,190,184,198,70,245,46,180,134,65,199,226,201,12,197,24,149,21,177,41,94,222,171,167,21,248,210,220,149,248,66,191,170,105,89,137,113,254,165,188,181,243,88,121,254,9,205,137,44,63,33,213,105,84,129,63,29,119,120,98,255,201,238,141,71,9,121,69,239,136,147,119,57,189,32,203,229,198,48,103,93,8,160,130,185,212,160,194,9,83,153,236,217,125,207,53,191,176,98,205,45,253,39,189,133,150,220,234,167,183,25,35,115,159,193,14,254,19,139,63,222,231,119,247,22,149,145,79,20,214,174,55,115,147,231,251,63,204,61,234,9,29,39,216,198,155,126,70,6,123,54,16,57,123,147,153,85,126,124,74,118,255,241,78,203,104,44,49,142,117,171,105,135,19,106,173,240,248,74,252,196,160,88,162,91,93,21,128,152,5,249,50,49,64,190,254,130,26,29,110,222,128,195,78,107,223,74,91,128,242,180,9,45,151,125,7,127,50,247,54,127,83,145,96,112,226,63,151,66,142,141,35,219,78,186,102,151,122,15,73,10,4,234,49,22,16,114,175,165,165,15,202,4,32,170,230,214,244,6,188,110,27,104,129,243,53,146,110,125,67,166,167,179,220,100,56,234,152,161,97,19,6,41,43,149,16,158,207,205,78,121,28,115,73,243,113,130,158,88,74,190,213,109,159,68,229,6,7,232,27,99,16,180,207,165,102,245,179,107,121,159,17,86,140,120,63,106,161,83,177,16,156,14,199,22,162,82,204,237,147,189,22,105,20,218,175,191,189,110,27,142,68,245,203,15,251,97,11,199,186,210,238,36,94,196,122,35,148,83,228,214,191,222,24,183,42,105,226,40,43,15,126,42,75,167,195,22,45,60,34,105,223,113,14,79,24,245,232,172,122,197,175,82,29,33,57,252,69,217,158,48,134,127,184,88,215,79,186,234,49,171,49,33,38,82,80,28,132,144,121,84,31,64,109,11,78,168,88,44,219,148,180,41,181,210,105,82,16,132,15,245,75,219,222,251,176,123,28,85,5,76,193,216,152,230,221,249,77,140,152,202,171,168,152,19,208,160,126,168,36,212,99,54,105,147,145,33,13,30,73,228,156,95,128,28,167,207,236,154,237,101,161,166,245,187,84,220,223,255,221,67,143,63,36,165,202,231,126,167,22,110,46,215,7,248,221,141,131,121,56,13,49,16,212,118,144,158,4,218,209,64,183,176,247,218,139,226,161,127,220,80,138,208,24,98,84,67,16,252,121,198,107,252,172,251,239,53,160,217,92,117,96,157,55,141,211,219,75,122,248,190,70,111,172,205,224,232,1,156,137,138,58,141,230,168,248,161,16,162,170,84,191,69,112,116,121,217,33,144,167,126,145,229,39,48,214,96,201,163,212,137,73,232,105,176,94,129,135,54,158,169,251,0,6,6,162,163,167,39,12,196,79,87,31,26,253,86,133,26,104,113,255,98,159,91,93,39,63,87,54,95,128,162,30,77,120,162,241,158,106,107,70,94,178,97,124,180,78,120,161,214,47,253,175,110,102,94,222,88,101,89,253,195,147,241,56,48,143,46,120,99,121,75,0,179,147,34,178,66,67,77,203,60,175,245,27,154,245,15,127,250,191,55,223,73,52,180,33,173,127,169,170,197,211,60,161,216,197,105,97,226,85,207,41,82,5,126,160,219,243,116,223,116,124,55,217,252,144,44,123,97,89,246,183,74,235,255,21,133,6,254,23,152,53,32,195,163,242,11,17,40,106,117,94,65,136,245,68,148,192,25,90,245,77,133,3,153,222,150,227,204,204,106,69,45,135,4,127,21,23,105,226,78,37,94,239,232,228,84,65,130,22,183,126,138,251,225,104,55,238,13,13,89,4,233,157,239,249,240,254,63,129,38,48,112,230,111,89,44,35,154,7,89,183,232,130,231,55,192,182,159,96,180,204,170,22,188,254,10,70,172,123,73,5,25,183,180,45,23,81,178,132,159,235,172,170,28,192,162,212,114,83,130,253,176,194,36,131,201,213,47,59,50,34,5,124,108,183,125,149,169,168,105,23,105,217,216,114,157,120,210,104,167,103,95,242,20,162,217,125,127,41,56,41,230,210,210,211,199,229,73,231,158,56,116,146,231,193,185,210,211,100,248,11,157,85,133,141,222,159,231,104,197,48,186,246,229,59,215,155,234,165,89,248,126,119,131,95,46,164,210,255,28,87,225,152,123,230,48,69,212,191,224,44,154,103,99,63,161,64,80,165,157,87,177,66,90,103,237,117,139,123,19,17,59,7,19,109,70,173,76,255,247,216,118,186,141,208,173,188,243,103,248,122,207,61,171,165,231,141,174,9,0,169,8,126,171,84,109,82,86,41,57,224,5,84,148,166,219,190,2,234,248,147,176,239,3,199,74,32,111,226,45,177,111,29,29,253,87,127,98,38,222,43,114,92,211,254,201,113,217,148,24,96,255,235,123,213,4,21,21,115,60,53,213,66,15,37,152,111,95,4,120,61,114,74,243,156,186,237,225,62,117,149,134,62,67,132,89,69,103,177,241,122,73,196,196,201,231,191,41,46,85,213,2,2,116,244,254,164,184,140,14,208,124,250,79,20,0,69,243,19,182,161,8,120,189,137,136,200,116,78,126,202,255,159,187,91,86,94,222,222,78,174,151,109,135,41,46,97,116,78,99,137,229,198,235,137,130,115,251,243,96,123,122,222,224,114,78,58,87,191,185,136,126,211,112,142,250,197,6,93,93,151,127,133,167,245,232,153,153,133,239,254,41,60,237,199,59,57,173,40,233,146,132,93,106,184,247,147,226,178,155,101,165,199,201,136,149,7,240,137,185,219,211,213,211,233,231,169,124,116,82,125,253,15,39,141,208,195,110,107,161,216,211,100,234,38,88,246,57,19,198,175,3,167,101,118,16,74,45,239,95,130,115,176,170,185,170,151,116,180,252,166,184,84,53,10,8,208,41,253,131,226,242,53,187,206,177,236,168,163,44,167,213,54,207,255,20,158,46,12,0,240,101,48,169,189,231,31,147,113,255,141,96,220,121,67,165,255,153,128,220,156,114,58,236,237,110,129,121,148,89,116,233,189,149,124,252,122,161,202,81,122,222,232,160,0,59,205,124,131,62,219,215,86,147,114,13,194,217,143,180,127,107,76,10,40,42,62,219,61,108,253,159,104,167,242,206,244,49,212,194,158,75,200,247,221,165,10,148,164,19,134,153,181,107,1,93,238,39,102,71,255,139,248,153,95,167,161,13,217,241,103,117,15,60,124,115,91,164,216,87,183,90,100,26,45,243,150,33,215,231,65,203,73,106,90,53,254,84,22,165,130,114,163,132,217,140,11,191,49,52,199,153,153,167,140,14,37,71,188,215,2,253,67,116,172,9,89,213,191,250,133,62,214,184,203,203,100,158,120,46,33,19,254,223,17,31,245,218,108,198,16,135,184,151,164,253,113,213,52,28,172,185,14,108,182,175,249,133,222,105,221,28,227,70,36,252,52,249,88,139,0,22,37,219,223,106,252,7,70,194,74,13,165,36,138,7,74,5,62,224,252,201,242,105,8,180,79,146,31,161,232,141,228,85,60,62,253,31,28,88,64,128,142,244,159,20,184,93,102,138,32,63,84,186,231,78,249,165,41,122,26,250,140,43,169,142,61,108,39,242,12,186,25,233,13,75,173,76,134,125,126,51,92,166,38,209,104,156,53,254,219,97,216,232,147,161,225,12,153,3,223,134,78,135,30,217,255,144,219,188,47,95,149,164,234,4,1,98,142,27,85,117,173,213,252,202,33,83,71,247,35,233,95,186,211,98,52,15,30,70,83,112,144,55,54,191,64,180,170,178,150,29,33,238,123,180,7,129,204,114,63,99,114,49,119,58,44,125,163,79,141,241,142,6,93,78,198,7,74,209,253,36,69,181,210,125,117,213,252,190,31,34,134,60,112,196,231,247,131,177,122,1,1,58,66,137,113,106,135,127,103,109,64,245,45,17,209,115,227,242,167,85,88,20,121,45,168,119,163,123,111,169,253,139,45,78,213,216,255,192,222,132,94,186,67,31,40,73,155,151,28,175,170,78,127,77,92,135,219,76,224,54,85,32,27,221,205,215,215,53,144,239,38,143,93,116,47,102,115,59,32,184,140,126,70,69,157,246,87,205,18,205,232,121,249,124,6,18,35,56,248,237,29,255,207,29,198,225,138,78,121,148,42,84,43,75,90,237,217,196,201,66,252,137,200,131,15,195,252,15,228,252,63,144,243,255,64,206,255,191,131,156,255,63,3,155,207,152,132,155,233,28,255,195,28,64,138,238,188,154,220,246,32,56,8,140,189,179,84,238,229,63,172,176,236,30,167,133,208,206,236,137,92,196,218,144,185,215,200,185,98,240,100,238,110,236,63,201,49,51,223,215,79,170,196,229,90,10,193,33,6,56,191,179,41,208,106,81,80,107,51,8,245,10,119,2,7,164,120,124,238,68,64,237,68,127,116,34,194,227,64,125,246,49,110,175,62,157,191,249,159,253,66,77,72,81,49,39,182,93,45,243,208,235,231,149,235,85,236,25,110,115,33,110,122,82,25,149,78,106,206,191,52,228,172,205,212,7,214,2,207,5,41,178,67,98,106,251,116,101,101,229,236,114,161,126,20,171,48,255,234,37,189,61,211,86,141,68,186,23,31,223,93,211,84,189,71,124,151,137,63,209,140,216,237,196,29,131,145,57,118,230,180,183,187,212,230,174,193,52,178,245,109,156,14,174,228,101,104,118,110,4,255,1,183,211,59,173,163,161,188,250,230,35,170,62,159,235,66,134,98,84,74,233,213,72,128,68,134,170,206,118,167,86,215,115,63,112,103,124,23,166,76,206,122,238,65,19,230,148,163,167,1,30,42,60,146,89,75,86,245,191,77,220,246,160,16,17,130,148,27,77,157,8,168,226,198,88,39,162,38,205,247,95,226,214,13,15,106,26,37,82,13,117,149,255,225,20,69,88,135,16,200,149,108,155,6,96,252,186,77,184,224,63,87,115,23,236,188,137,98,94,57,190,26,174,230,62,158,37,170,147,33,24,113,186,251,31,119,133,232,140,201,200,228,60,65,202,228,122,105,199,88,164,232,135,31,76,189,221,122,117,156,155,14,219,30,148,213,245,108,166,168,165,59,25,72,24,121,190,236,74,230,149,221,175,90,185,173,189,236,191,163,195,219,235,98,113,127,202,207,62,164,25,26,60,207,56,107,48,86,182,245,178,241,151,220,238,109,171,101,151,207,38,73,121,61,214,99,92,253,95,254,221,144,98,239,4,176,40,205,56,168,56,29,38,160,29,161,145,244,110,214,94,239,103,153,243,3,239,106,156,222,183,82,71,250,144,219,234,238,52,237,55,23,53,174,252,22,118,251,191,199,180,237,8,31,59,186,60,155,239,39,247,221,70,124,114,206,83,3,31,211,173,109,99,34,222,32,251,59,87,126,190,239,227,255,7,46,118,27,215,62,124,7,157,253,106,127,127,85,85,169,183,11,207,255,149,56,244,48,6,101,122,216,232,235,255,186,143,162,59,195,23,187,195,163,72,58,148,146,177,117,229,157,97,143,255,172,90,186,156,123,147,134,254,171,69,234,226,220,203,50,223,104,146,120,121,97,107,245,189,255,10,51,93,161,217,233,70,215,166,246,68,237,82,239,251,130,216,159,153,131,199,217,205,3,15,85,132,115,88,181,86,146,71,253,238,203,30,250,230,117,222,223,112,110,143,243,149,183,232,168,105,79,179,209,31,185,124,229,114,236,100,243,195,32,67,173,149,83,217,173,191,64,181,12,204,204,106,229,51,185,82,255,153,226,210,131,196,161,244,168,193,185,159,181,27,111,147,162,206,134,149,228,183,203,13,7,196,19,51,172,188,188,6,117,146,153,202,135,214,213,83,100,114,224,212,26,99,230,186,252,138,107,218,173,103,84,52,11,12,38,6,2,95,57,222,140,207,101,80,8,209,174,109,250,30,7,174,118,69,81,49,167,183,93,125,230,176,167,139,165,138,117,48,48,134,73,53,63,16,223,79,59,0,175,185,84,90,254,99,8,247,2,2,116,222,153,197,84,31,78,230,158,42,150,247,156,118,60,206,55,75,231,116,231,133,0,61,111,244,251,0,101,189,167,11,18,172,123,169,2,167,226,167,174,28,232,83,159,102,225,229,141,85,253,83,159,250,113,224,169,166,224,13,194,22,173,172,140,7,173,229,254,223,43,164,251,240,52,90,65,176,231,220,197,79,248,167,253,62,71,15,34,219,252,4,205,102,54,239,31,232,137,140,75,58,132,6,94,25,146,222,47,118,108,23,134,193,102,155,82,254,144,141,80,106,201,255,6,89,231,166,158,24,200,198,215,130,113,183,126,62,22,168,28,24,14,248,231,172,146,82,68,115,43,57,5,201,16,91,27,154,251,147,192,87,177,149,134,54,68,207,21,186,24,249,159,92,39,35,0,33,166,197,248,208,129,143,79,242,32,177,11,79,52,126,157,108,20,51,113,210,194,149,222,251,32,101,57,77,77,163,116,209,81,53,239,176,179,160,105,12,25,143,46,140,224,63,5,15,179,243,243,208,208,103,8,166,166,62,139,200,208,184,42,169,71,192,240,118,131,221,157,14,96,217,12,251,111,117,176,93,60,172,54,115,155,23,63,209,155,183,112,144,176,208,137,94,182,78,243,104,10,121,61,178,54,193,210,210,151,116,208,71,162,3,219,79,35,221,108,156,14,143,76,86,44,215,199,30,27,154,205,142,200,151,253,196,253,115,14,142,155,212,203,249,235,93,58,115,254,222,85,250,207,154,7,109,8,194,251,111,117,116,92,124,126,104,236,37,157,133,174,173,241,190,150,123,72,128,212,47,172,189,34,34,54,185,144,233,205,198,179,44,118,219,223,87,191,143,25,78,136,218,151,231,176,31,94,153,15,167,233,111,52,9,157,249,39,27,36,194,191,201,191,95,210,127,95,215,101,109,206,172,48,220,46,85,116,250,45,78,125,250,180,85,200,255,21,208,173,208,193,0,166,119,191,179,255,167,52,233,126,21,225,27,83,183,67,130,19,198,89,14,4,250,83,207,237,7,149,191,212,117,43,232,62,42,45,244,143,189,179,82,177,31,81,21,248,135,42,240,19,157,140,168,131,43,224,181,208,209,142,119,154,55,87,33,136,197,95,101,133,105,128,208,116,235,104,117,239,161,120,31,104,71,195,197,147,225,134,97,101,113,202,106,84,160,101,86,84,68,68,195,4,108,195,245,63,151,212,157,3,82,29,24,191,241,126,20,252,63,18,117,232,247,218,188,99,202,244,18,132,7,251,121,250,228,192,183,123,158,25,26,77,223,12,63,105,31,60,102,203,62,137,242,55,253,83,155,186,75,173,254,88,144,243,84,229,63,178,178,230,37,197,0,106,90,230,156,227,15,89,214,247,179,21,246,180,97,151,250,131,100,76,109,127,55,127,248,167,54,245,219,252,127,43,240,184,11,212,52,244,25,194,255,171,192,255,87,129,255,175,2,255,95,5,254,255,162,2,167,167,39,224,55,167,23,15,219,187,96,96,30,93,240,219,235,174,41,243,10,241,49,227,176,93,23,41,200,230,82,77,65,19,39,104,244,228,217,235,2,240,78,70,90,102,147,122,26,46,190,88,231,174,36,62,37,198,109,220,5,200,175,177,28,9,1,80,169,232,63,210,230,215,167,87,160,208,157,113,244,108,164,205,238,45,58,133,157,121,254,173,141,30,109,244,79,42,142,126,115,55,47,241,218,13,189,158,41,212,176,147,136,148,243,224,85,41,231,237,171,82,163,41,24,10,9,47,165,217,172,69,203,108,114,245,103,41,175,193,133,178,82,155,71,87,93,87,200,193,87,156,52,126,250,187,138,185,170,228,0,163,147,6,28,154,55,216,165,201,236,219,12,140,15,55,202,68,240,136,55,178,238,83,255,248,140,63,153,171,106,62,15,249,42,79,222,158,254,121,149,12,190,229,216,175,224,85,35,38,235,153,51,226,217,163,57,214,34,136,88,242,30,118,204,214,185,215,110,156,169,153,220,253,221,112,1,160,18,117,126,249,146,102,194,15,97,242,120,1,34,167,205,71,199,88,198,249,147,114,54,41,191,58,152,73,97,208,194,111,33,51,83,42,45,136,81,91,17,232,19,247,80,133,158,229,180,153,175,207,249,139,7,237,65,86,116,244,244,87,76,64,143,15,97,28,82,59,143,27,20,54,202,251,239,214,118,90,152,229,138,169,166,7,118,0,41,254,91,181,120,104,39,116,165,225,152,233,88,105,100,191,220,184,190,123,79,150,230,122,122,168,247,152,215,128,28,111,239,194,17,37,53,240,241,229,123,183,163,75,221,240,240,21,88,195,189,242,194,62,204,53,225,205,113,8,62,46,57,120,231,138,39,245,24,156,35,192,32,224,122,73,97,30,136,249,191,158,145,128,3,107,32,55,2,121,239,128,67,233,32,63,102,222,128,188,127,34,230,39,240,24,96,148,109,200,138,178,141,10,120,25,122,109,126,90,165,101,240,226,142,135,232,61,127,140,21,210,239,251,172,229,242,75,142,219,106,198,172,88,60,178,160,66,246,120,84,232,8,87,108,81,78,149,50,125,230,246,181,92,128,196,127,237,121,204,12,192,251,14,160,198,89,247,102,33,234,177,150,10,143,230,211,194,170,119,175,156,97,147,226,142,177,13,76,99,94,49,121,50,19,55,118,148,219,121,210,174,61,97,198,210,127,245,238,214,71,70,241,202,142,142,29,66,146,82,152,179,28,255,43,220,80,77,194,131,177,248,180,182,147,94,216,34,116,209,88,214,131,188,74,171,220,83,59,90,168,113,63,236,93,179,20,22,147,171,52,28,199,25,128,37,199,197,106,207,217,148,49,42,199,223,63,176,99,43,62,6,102,102,179,103,219,108,17,135,138,222,143,204,57,158,38,157,232,58,162,107,15,95,9,161,174,158,221,248,254,119,215,170,153,254,91,223,223,137,43,90,180,113,93,243,252,118,151,179,138,133,95,185,151,61,47,160,235,226,155,251,83,70,22,94,125,254,240,183,215,197,234,52,211,125,140,110,223,136,178,235,235,207,121,9,167,108,193,125,222,88,120,155,254,51,121,54,48,148,55,21,125,189,182,179,133,45,187,197,156,94,138,243,238,47,63,44,214,161,165,167,191,194,230,205,112,120,223,252,126,60,68,40,154,237,225,151,176,135,162,53,47,132,76,91,144,181,155,9,178,228,237,233,66,35,119,207,219,57,147,153,111,44,23,79,1,247,86,178,202,121,164,31,103,200,206,37,121,44,70,74,104,177,12,108,215,189,221,46,105,62,239,17,37,183,246,44,241,150,251,123,200,236,59,251,209,226,7,141,123,244,9,223,210,85,208,203,168,137,113,47,79,79,224,199,219,216,213,61,242,22,198,71,91,129,152,1,89,200,124,227,223,15,46,44,143,7,36,167,191,186,197,213,222,91,233,232,135,70,227,235,70,228,247,86,26,113,8,202,94,54,176,96,77,114,216,129,31,181,222,33,219,217,19,235,10,107,173,121,242,12,58,230,61,226,130,139,144,26,95,193,138,10,49,89,236,218,37,186,204,246,114,12,128,224,181,137,87,31,4,141,192,41,164,177,126,115,183,101,164,190,163,103,59,147,220,74,0,32,57,83,215,236,200,177,83,158,224,162,170,44,125,158,186,141,76,241,42,234,35,71,123,13,77,137,81,0,96,157,43,162,251,36,215,205,47,35,216,193,96,38,133,183,3,148,24,196,222,67,28,185,67,22,239,155,47,139,171,108,212,76,184,217,82,88,214,33,227,218,204,227,179,225,162,255,230,65,99,98,75,140,32,26,141,171,110,35,77,3,40,143,58,129,148,26,115,151,242,190,209,29,44,18,223,105,97,27,103,200,165,183,94,177,69,247,113,206,230,12,178,127,183,106,107,230,28,193,139,250,191,154,32,55,53,118,169,108,97,74,152,239,122,175,166,204,41,130,193,100,94,126,209,99,183,58,162,209,152,35,122,185,194,188,205,74,199,226,227,83,169,197,200,138,192,251,225,87,136,86,42,141,15,0,43,183,200,219,172,163,72,56,212,235,217,114,211,39,133,46,78,25,79,246,51,68,98,39,28,199,150,234,80,33,164,227,53,236,72,153,201,210,132,54,2,58,202,138,125,132,253,22,180,69,167,199,147,200,118,99,185,200,186,157,188,221,69,99,140,19,245,107,204,176,151,45,167,73,229,32,143,247,96,131,5,140,56,227,218,155,163,235,53,87,78,184,212,86,84,248,193,244,61,222,127,78,22,71,198,140,108,248,15,149,159,123,252,133,207,181,71,83,202,171,249,156,135,6,174,98,42,92,100,39,32,154,70,234,24,192,191,184,135,75,155,104,180,109,170,195,193,237,90,156,182,219,36,14,251,94,49,236,148,47,215,114,135,73,254,71,176,154,101,19,200,166,79,158,180,209,131,251,196,170,253,88,106,244,17,20,7,111,151,24,168,212,215,146,238,139,224,129,132,236,46,104,195,23,217,10,118,71,231,20,230,142,24,241,149,233,52,0,246,38,143,41,60,242,37,19,231,230,108,217,64,123,107,111,48,158,205,60,144,2,136,253,44,186,142,84,70,35,122,175,233,74,221,167,41,92,210,65,19,206,58,155,175,72,124,35,182,159,6,118,34,83,194,56,140,114,207,33,185,232,165,10,253,177,184,18,195,92,214,95,110,117,59,117,23,25,158,118,168,223,142,138,38,147,117,69,223,195,180,19,133,7,138,91,44,115,184,134,158,135,239,185,163,3,186,146,243,138,224,46,156,32,127,119,223,111,193,42,64,51,101,158,111,241,134,95,179,125,171,149,103,29,50,158,51,29,93,8,208,230,68,187,131,103,68,162,75,102,140,204,171,243,145,21,169,186,141,89,169,141,131,37,54,99,189,185,250,36,246,221,50,107,14,133,66,92,236,78,183,132,153,109,227,73,41,79,56,41,63,232,182,90,108,178,149,182,187,65,195,4,121,83,10,69,156,77,68,11,233,103,221,140,29,252,60,242,116,109,228,22,63,45,148,97,6,28,219,139,194,144,92,208,31,68,203,148,216,207,67,55,116,183,194,153,142,14,117,84,78,188,22,202,212,118,97,98,152,90,42,105,62,143,91,70,77,224,244,174,79,2,203,126,115,1,212,32,109,226,145,202,244,68,171,104,189,161,39,37,100,191,116,33,42,12,161,208,45,212,74,135,195,153,241,93,211,234,37,118,159,134,80,206,193,222,32,148,167,208,29,234,66,36,116,25,140,27,243,177,183,35,218,209,13,198,180,190,37,226,208,184,156,244,200,82,197,113,71,139,14,91,21,55,6,147,203,170,128,215,171,10,139,237,5,187,126,150,228,176,52,36,72,96,224,119,14,181,126,161,158,62,237,137,238,244,185,67,219,230,78,89,0,158,17,37,212,254,140,158,224,39,34,252,118,146,255,100,220,36,122,49,47,255,107,143,234,89,77,22,78,193,100,240,82,98,178,60,164,2,48,115,221,230,243,203,71,164,120,163,228,254,35,46,59,165,186,233,202,85,45,49,32,15,124,141,44,63,24,100,46,228,212,161,162,16,176,242,179,103,174,248,35,195,147,228,206,91,211,47,151,244,238,220,107,131,77,177,186,162,198,124,124,18,34,53,244,155,73,51,226,112,119,97,17,215,228,228,100,92,113,227,41,15,183,90,83,238,107,31,126,188,86,175,190,102,243,121,59,119,209,181,142,104,103,188,124,194,88,150,212,190,160,197,239,195,230,185,184,154,165,24,97,187,62,25,204,116,11,30,113,242,236,151,217,79,172,218,158,47,196,170,115,128,83,3,159,24,178,7,109,154,178,76,209,35,41,158,60,124,252,148,238,108,182,152,190,62,111,31,147,243,230,174,85,113,8,51,183,119,182,241,171,94,201,43,159,88,133,251,17,89,86,253,239,236,83,22,96,123,211,0,123,251,167,217,102,69,29,218,119,179,115,103,227,205,97,210,91,9,239,118,61,160,239,90,211,23,59,228,183,228,32,15,150,173,123,58,35,62,120,127,235,245,4,116,16,175,102,232,71,55,144,209,43,31,25,73,108,144,18,102,77,119,159,166,56,227,109,84,9,9,53,230,42,11,252,136,173,198,22,121,80,118,6,48,165,102,210,251,251,191,52,93,84,191,137,77,132,175,76,103,237,229,73,18,33,157,125,228,3,231,58,110,215,52,20,93,133,7,9,26,255,174,144,229,217,121,121,123,245,175,117,31,166,42,236,164,251,200,57,94,216,168,29,72,91,97,201,170,83,255,15,118,101,91,236,225,196,4,136,128,93,249,106,78,29,90,33,84,99,96,153,96,39,74,155,162,212,145,176,131,111,219,197,97,197,208,75,215,179,169,34,138,166,11,202,58,90,85,162,115,192,91,154,140,83,73,254,107,45,184,86,17,228,134,96,45,121,7,91,1,235,120,65,46,143,98,52,123,15,48,11,80,237,137,110,210,108,72,157,170,150,78,176,196,165,133,1,194,221,57,128,22,67,251,38,153,109,223,35,109,198,175,2,230,112,212,103,182,27,173,116,199,45,149,117,110,130,185,136,201,203,10,243,65,133,172,150,216,11,11,136,157,233,56,4,254,109,231,123,89,149,115,238,255,156,103,206,67,116,183,33,150,142,122,158,88,209,47,117,108,149,155,73,211,213,28,142,55,177,62,238,83,79,62,230,203,93,24,101,48,122,74,102,62,245,234,107,97,17,16,118,171,215,237,187,210,222,3,72,151,153,38,215,201,76,127,242,222,28,16,125,132,73,174,75,19,161,48,134,56,93,132,90,140,7,193,158,184,229,120,189,253,240,185,199,123,196,21,155,165,149,24,111,107,190,186,107,125,22,143,161,212,201,238,204,167,67,83,191,24,15,59,21,232,170,154,77,220,187,93,236,209,41,63,0,93,125,1,242,68,141,58,165,135,23,236,153,150,217,17,3,186,181,97,107,49,111,233,246,39,254,78,233,206,247,98,138,222,136,176,164,238,249,67,117,193,196,218,223,240,32,48,245,68,131,99,76,32,49,101,185,191,229,86,247,141,64,199,254,111,72,45,168,75,96,197,212,211,19,103,187,203,52,214,122,67,221,143,159,92,246,4,39,217,137,98,115,44,109,251,12,147,251,197,244,174,170,154,171,168,132,237,226,124,48,88,239,209,213,50,62,148,232,88,178,207,248,217,241,145,116,229,138,237,252,222,18,81,184,166,71,22,149,246,40,135,233,67,150,173,80,113,127,190,58,66,224,241,204,136,173,136,32,86,179,124,65,215,17,179,98,155,170,153,248,117,183,184,76,154,40,134,160,175,35,253,5,228,248,7,105,123,111,221,236,159,61,234,247,26,5,143,9,68,224,134,220,48,36,255,71,26,3,121,154,252,73,55,161,150,215,206,108,124,230,118,171,132,224,107,7,174,212,110,116,95,83,135,20,85,207,165,64,43,86,44,197,177,109,19,246,8,232,154,191,247,144,45,39,170,71,75,118,102,225,74,166,11,123,54,111,76,208,237,97,131,89,56,108,70,132,236,229,155,83,109,108,9,109,138,50,235,134,104,226,179,95,153,174,190,77,152,141,213,215,106,25,56,174,151,184,236,202,95,249,30,67,195,174,61,152,115,169,130,238,98,42,71,241,149,113,208,119,139,11,81,223,79,105,101,148,26,252,186,213,9,204,160,61,195,23,107,224,241,27,68,248,243,31,141,122,153,91,164,216,135,27,68,194,226,114,170,213,51,229,212,26,48,184,230,211,242,66,54,34,82,28,178,119,78,25,151,163,95,93,151,118,30,110,173,244,69,132,123,56,61,53,56,72,42,98,68,97,119,105,217,21,237,226,127,107,172,244,221,205,5,58,184,75,245,231,180,59,97,213,175,248,85,134,46,167,221,27,114,100,207,38,68,121,15,186,31,67,125,63,202,61,20,235,9,242,10,59,239,231,96,17,253,143,126,158,35,99,90,66,94,68,205,147,94,40,121,29,209,121,132,171,186,219,122,44,206,136,16,149,254,116,3,86,148,136,116,205,241,40,33,159,238,250,127,216,123,203,168,170,190,232,109,148,82,233,46,165,187,164,59,15,141,116,169,32,32,168,128,116,119,30,186,75,26,41,17,16,144,20,164,227,128,148,116,119,119,55,135,60,113,7,194,175,222,251,254,239,29,247,235,29,239,24,251,203,57,238,179,215,90,115,61,243,153,207,156,107,186,241,19,0,15,144,72,203,185,204,176,104,124,117,46,214,243,83,209,46,170,158,189,19,216,132,92,207,0,48,129,244,139,131,240,253,207,50,105,190,124,47,54,69,58,39,97,105,188,102,106,196,98,86,207,65,122,36,207,181,223,204,205,140,219,126,158,44,173,99,241,211,158,255,64,205,58,158,191,186,233,45,212,221,124,185,232,101,123,210,73,114,169,61,76,212,55,101,202,76,157,104,247,250,26,168,154,149,113,107,117,40,90,154,210,81,227,135,82,169,255,107,201,29,163,48,172,229,115,169,111,204,255,99,115,139,45,138,53,15,189,39,164,225,36,173,86,6,189,178,180,241,176,161,230,98,32,240,205,227,87,151,37,209,60,35,122,0,101,246,234,151,177,60,19,122,130,52,173,239,177,242,183,165,106,88,202,89,236,154,178,154,49,162,235,70,149,216,58,219,93,134,92,110,125,180,200,192,167,243,78,182,107,209,130,23,59,28,13,219,160,63,45,216,129,148,215,225,201,135,63,186,41,93,152,50,236,3,68,215,66,1,206,192,43,16,252,12,49,179,118,201,119,78,213,151,157,77,48,178,169,233,180,183,79,13,190,91,51,155,63,123,248,125,76,79,236,192,246,244,12,47,243,120,185,165,162,143,4,34,34,59,48,8,15,42,117,27,175,187,102,213,35,222,43,7,181,224,184,11,80,78,121,169,122,21,88,204,72,64,142,219,63,134,238,245,234,240,71,234,235,58,245,185,126,4,199,142,13,119,242,209,201,71,85,24,95,112,0,202,119,5,102,76,18,220,167,1,221,154,6,43,91,156,244,231,224,154,92,223,6,41,16,219,156,157,122,237,162,167,21,113,120,196,204,244,96,83,84,214,117,23,185,187,173,182,100,180,137,84,237,180,132,77,150,28,207,223,34,74,29,3,23,119,119,108,160,189,243,223,41,237,45,146,7,176,242,232,205,33,20,162,61,200,141,18,68,201,19,48,236,0,240,186,8,61,60,31,83,119,219,202,116,51,140,125,243,60,116,248,178,124,89,131,152,112,212,217,126,82,206,166,126,207,124,154,80,204,178,38,120,68,228,141,149,153,122,123,40,206,80,194,157,89,36,220,243,193,238,135,141,71,45,222,64,119,77,7,187,22,112,242,220,196,183,168,198,219,44,175,249,223,159,232,108,220,92,229,216,123,207,182,174,149,89,18,159,242,88,237,253,104,161,36,42,240,75,150,95,56,55,175,58,213,209,125,31,252,173,160,48,198,184,59,134,125,30,76,36,232,126,252,213,182,118,193,245,204,95,108,230,123,233,47,226,168,53,254,71,240,155,27,54,31,135,51,139,103,187,84,115,165,28,153,205,39,61,210,123,155,116,37,124,207,138,106,130,79,155,243,102,65,238,106,109,0,67,163,3,49,67,112,178,100,65,145,155,243,180,186,158,121,201,98,111,141,209,250,216,126,203,1,9,201,224,131,164,247,107,53,120,132,138,58,144,20,134,242,175,26,68,162,10,245,57,143,190,155,89,128,120,38,70,29,75,237,244,7,140,75,56,124,87,71,106,210,221,212,123,68,142,228,250,147,144,190,93,179,203,92,254,45,246,27,12,164,78,108,248,85,201,206,34,31,195,108,36,103,75,234,198,43,139,122,181,88,249,140,160,138,0,134,106,171,55,174,51,57,111,3,24,158,177,231,129,157,126,250,14,112,2,175,149,5,109,231,133,46,219,158,80,5,17,148,64,46,15,192,71,64,184,215,165,12,25,123,158,197,230,79,53,173,249,159,106,154,110,218,85,44,11,167,125,156,84,9,181,39,37,100,188,182,226,32,193,3,71,159,45,159,159,17,194,157,102,209,216,60,113,77,129,112,222,236,235,159,141,39,93,100,103,22,39,63,187,180,216,169,243,186,180,37,169,81,124,44,61,106,90,202,82,191,153,83,246,113,72,76,57,162,150,127,216,186,21,217,43,209,126,241,218,69,121,230,179,60,28,210,13,216,61,68,204,159,0,13,170,97,232,76,159,249,33,34,163,111,29,87,10,62,138,154,218,39,242,85,181,87,230,70,79,126,199,171,109,138,114,255,42,182,93,208,104,226,55,196,234,127,255,233,120,118,68,176,140,190,157,217,43,241,44,235,102,214,47,35,2,86,165,111,247,166,73,170,229,125,205,41,50,121,135,196,170,124,61,107,74,76,74,23,156,214,63,41,52,24,189,161,102,177,149,120,129,43,106,90,154,6,185,221,95,222,30,201,53,230,17,213,112,209,121,235,146,148,46,226,98,105,147,221,60,186,77,253,200,221,178,237,137,106,254,107,161,161,81,230,66,220,218,1,129,185,126,232,121,1,192,133,19,4,169,212,55,142,230,255,117,88,2,17,242,52,63,247,220,235,92,135,93,95,204,217,185,209,41,196,56,23,151,183,120,246,1,29,34,126,54,16,232,183,88,84,139,104,244,17,236,98,7,177,44,236,150,70,160,65,60,213,30,175,30,121,122,77,223,119,227,143,46,216,183,99,129,51,225,175,225,230,244,64,160,33,77,59,41,2,235,254,41,231,214,235,72,221,150,161,225,197,14,30,190,134,18,221,46,204,244,111,234,218,216,242,70,213,145,134,177,207,248,123,107,63,101,233,232,219,84,119,173,122,44,233,35,77,194,44,113,74,55,18,103,147,63,100,106,91,25,239,222,159,217,150,33,32,230,56,207,101,125,254,71,82,228,177,46,123,9,151,158,114,47,199,125,111,71,42,188,164,141,124,190,234,123,81,165,92,74,87,63,28,105,205,185,53,253,153,255,153,102,46,66,79,178,64,196,118,43,50,142,179,232,81,83,149,190,211,0,127,230,228,215,250,245,120,229,249,189,242,238,106,127,233,56,234,161,182,0,210,206,229,246,182,39,84,214,58,148,49,150,194,233,110,139,62,221,22,38,163,229,64,168,213,229,111,186,216,171,214,174,154,236,153,73,213,44,49,225,241,225,120,86,176,67,55,5,201,226,92,46,18,22,58,99,6,16,118,109,123,115,190,115,13,251,64,205,154,76,53,181,55,179,240,45,245,76,248,26,153,168,0,143,255,246,8,4,242,90,13,103,154,87,160,242,89,135,179,124,113,190,222,72,105,196,18,156,230,42,1,38,108,205,47,98,20,171,113,232,96,6,184,120,185,186,230,60,75,75,200,158,95,15,242,71,198,32,48,209,29,45,46,111,153,45,159,227,245,186,176,62,42,255,100,224,178,177,167,247,28,55,79,21,38,242,186,4,40,182,233,54,23,104,71,199,80,43,95,100,5,79,165,254,54,226,101,250,17,62,238,235,64,56,154,172,111,187,19,50,231,236,246,198,5,114,38,245,132,98,93,193,166,249,108,80,84,164,111,231,26,118,123,228,22,74,225,154,10,2,66,212,40,137,195,252,62,183,124,127,172,165,255,227,111,14,98,192,99,134,0,86,227,199,195,44,255,85,197,252,211,89,92,247,58,20,60,47,207,227,156,142,246,68,31,125,191,162,29,251,176,208,142,114,3,182,5,132,49,229,177,156,179,88,137,212,60,161,244,30,134,99,60,153,192,191,166,55,246,200,66,23,8,242,53,15,126,82,146,95,217,26,132,191,223,120,212,114,248,217,170,220,1,120,5,165,146,38,211,243,106,57,254,133,33,241,59,209,76,195,251,253,211,131,250,41,67,95,89,149,249,82,77,229,242,166,211,8,209,147,142,132,121,197,11,187,235,247,239,45,107,89,180,191,233,198,227,198,135,109,88,149,210,216,116,83,122,149,52,158,246,178,249,32,20,126,160,216,136,96,130,109,10,130,170,129,160,19,237,20,139,60,101,110,251,124,234,145,38,235,149,150,151,176,21,244,205,207,10,201,253,0,23,167,8,36,59,244,15,157,244,159,25,237,154,193,242,183,179,33,246,234,37,110,92,58,13,219,148,217,62,206,173,216,65,55,221,25,191,136,110,248,102,202,72,37,44,75,2,71,9,135,88,97,152,172,186,238,109,143,72,116,69,41,77,158,134,144,47,186,27,63,180,247,239,172,124,45,178,13,101,175,157,183,44,227,163,79,117,67,92,240,21,176,248,82,45,107,67,191,208,180,53,57,52,248,124,49,15,186,63,90,111,240,87,233,217,208,15,79,122,225,214,158,240,95,177,112,20,173,99,4,3,54,119,148,95,252,118,169,112,184,147,196,104,31,153,161,61,20,231,242,36,9,215,50,44,118,69,216,160,72,4,214,120,209,114,35,25,160,78,28,195,255,152,152,163,121,93,171,118,193,117,238,13,241,138,59,119,183,1,245,92,125,31,71,227,21,30,215,181,175,151,38,166,125,161,247,163,128,111,42,30,185,28,132,121,130,94,71,205,41,162,203,126,200,144,162,192,199,88,142,58,6,14,193,250,166,73,175,188,185,152,215,73,122,143,126,46,171,175,241,79,246,50,39,207,67,247,236,123,222,138,55,0,250,8,182,20,159,149,211,81,14,163,22,209,200,132,232,86,71,232,241,195,223,186,65,165,83,110,186,155,86,157,250,251,158,96,160,75,53,212,129,14,103,34,194,115,129,17,183,141,137,70,168,222,61,158,251,211,116,210,142,192,52,254,72,82,204,209,182,154,94,78,226,222,61,74,140,160,229,204,210,137,151,110,160,115,33,50,181,127,178,172,68,4,196,28,137,9,114,131,127,247,110,98,24,182,186,249,23,87,125,14,166,37,102,190,144,184,221,95,99,84,73,93,238,162,228,158,140,54,4,250,8,154,199,49,154,255,150,71,78,3,238,155,83,190,31,11,178,56,200,121,235,182,192,15,162,4,52,191,97,39,94,86,88,94,127,114,208,89,241,190,125,254,46,35,5,169,13,255,254,68,199,158,183,150,251,196,195,68,54,115,198,170,164,37,196,200,104,123,51,221,238,98,39,114,139,179,170,159,199,182,32,211,213,145,78,62,234,119,57,93,140,146,230,107,50,187,166,31,100,110,215,66,110,11,46,83,19,73,205,215,155,233,183,120,210,75,144,77,193,133,213,72,206,172,20,157,231,192,78,34,29,231,59,25,49,103,146,160,26,33,55,8,174,14,96,106,233,253,193,234,132,81,103,34,108,185,174,242,195,251,81,217,103,155,207,89,71,55,123,229,110,197,229,63,26,64,135,219,240,112,83,137,21,53,209,3,62,183,195,250,173,201,20,206,180,253,103,167,173,49,111,245,197,56,151,116,234,176,103,54,210,95,49,102,81,93,6,139,236,74,254,86,232,38,59,27,209,83,91,235,142,117,35,43,1,73,165,24,139,216,73,118,35,44,185,46,221,76,214,126,168,17,227,68,64,164,42,168,186,96,129,144,114,248,105,253,198,255,11,49,87,238,143,88,47,84,153,96,240,129,110,43,53,139,127,69,199,231,47,253,171,107,41,9,136,149,106,65,40,89,245,151,167,193,158,236,44,68,176,156,82,186,243,126,222,161,186,130,44,207,94,44,74,177,105,118,16,228,84,66,163,234,180,151,205,237,224,234,136,166,63,234,41,47,196,83,232,243,99,219,245,223,159,108,51,93,38,209,16,211,5,78,71,158,73,199,2,96,117,233,2,54,159,181,185,204,38,94,233,128,253,191,10,168,129,199,6,85,51,132,70,154,111,15,27,213,114,115,86,175,163,165,98,92,79,111,234,70,11,41,198,31,235,41,40,190,38,179,249,57,226,125,203,89,104,5,60,106,190,132,84,171,125,230,235,41,7,84,7,60,194,225,151,86,70,20,175,121,196,86,145,236,163,118,131,231,78,28,228,181,153,229,128,81,83,33,145,124,75,201,4,27,88,176,95,196,246,217,255,94,247,87,70,190,141,133,136,36,221,156,243,130,242,223,199,51,116,254,195,35,69,24,101,122,146,204,165,49,131,190,227,42,6,172,72,168,207,101,253,171,107,158,174,89,23,61,159,99,61,220,241,2,214,227,150,175,175,113,122,198,18,216,85,249,13,199,80,1,219,18,255,74,53,49,12,252,88,214,136,133,184,31,253,251,12,230,18,101,95,249,72,32,243,213,82,35,71,25,234,221,184,24,72,14,60,73,31,173,188,193,193,123,250,113,83,113,234,109,117,212,24,52,118,15,179,210,101,70,66,9,34,70,23,13,254,87,237,191,2,247,209,115,220,60,206,150,177,157,90,220,57,191,175,120,119,234,205,220,135,233,81,32,235,251,84,141,236,150,201,197,22,161,116,165,111,181,85,244,128,191,150,70,135,164,55,145,248,159,146,61,62,254,159,131,149,145,157,20,141,42,237,87,40,184,219,254,146,164,146,22,127,189,109,14,231,16,51,158,246,127,62,61,216,254,33,73,250,116,29,116,187,184,230,36,140,136,136,130,251,66,138,186,83,82,195,90,231,35,65,52,190,216,195,193,180,4,34,146,244,134,149,182,101,208,127,120,219,247,224,203,247,6,200,21,165,123,173,6,185,44,130,191,243,163,125,58,158,255,47,61,10,17,208,216,63,203,248,18,238,231,243,194,146,156,225,239,222,0,13,70,68,36,105,83,75,213,221,128,127,141,71,134,52,161,166,108,242,131,186,229,209,226,99,98,197,63,125,128,209,121,152,99,86,140,164,66,76,216,201,235,226,234,249,255,99,15,189,37,18,69,196,147,157,189,35,52,87,231,73,66,247,224,63,71,81,195,207,164,255,126,233,220,34,41,249,131,114,206,254,63,47,157,251,255,223,75,231,240,164,209,248,5,94,253,251,127,10,160,234,114,253,190,17,98,43,161,233,192,186,179,38,31,145,134,70,222,119,151,160,209,200,39,120,216,150,158,10,21,15,185,186,35,42,46,46,171,130,168,22,198,191,176,52,75,140,138,145,127,151,64,80,100,218,208,125,194,69,68,193,39,217,174,248,82,239,243,226,27,169,144,153,192,72,199,145,207,247,88,4,36,120,108,243,25,194,207,220,194,197,43,15,206,71,248,210,104,205,65,248,158,156,57,151,101,132,59,144,87,223,195,94,202,209,48,203,225,21,209,170,126,70,250,250,34,165,140,240,209,39,67,89,79,172,102,70,201,66,255,56,132,29,143,35,184,207,86,255,254,194,173,231,141,143,199,18,189,93,95,127,154,48,47,40,45,179,145,215,204,76,7,69,246,221,71,198,47,58,93,3,253,213,197,149,225,126,168,97,127,95,146,202,40,117,34,97,234,160,62,218,113,124,138,235,187,127,66,240,122,97,164,56,67,100,244,180,224,168,111,7,9,23,17,239,238,242,79,75,241,123,141,58,208,228,82,28,255,223,159,71,162,92,181,122,209,9,234,209,140,211,82,121,68,220,125,9,84,40,136,44,75,44,226,85,37,218,65,255,251,215,73,126,190,27,102,147,159,95,213,203,74,162,252,115,125,225,71,178,69,253,21,185,214,176,109,98,102,165,187,206,137,68,75,141,68,132,212,243,97,241,110,244,114,212,87,159,253,99,30,238,124,199,72,71,29,56,172,242,58,135,53,230,95,163,251,161,254,84,70,32,200,128,104,52,236,75,29,196,199,223,205,71,135,33,78,71,163,178,106,255,131,26,8,235,109,201,175,87,6,247,19,224,144,147,124,156,195,241,106,129,181,228,63,63,143,67,48,12,201,123,10,224,127,116,119,151,121,38,130,168,34,164,91,175,119,210,148,144,246,110,42,247,87,102,148,31,166,116,102,201,175,196,183,120,15,203,249,115,165,106,33,37,237,12,244,142,36,126,43,186,186,187,145,139,23,207,252,11,75,97,11,119,75,173,0,47,81,9,178,105,209,94,64,241,87,17,63,57,218,135,39,113,105,227,198,73,153,127,43,148,39,146,70,249,183,21,24,253,253,230,252,143,103,133,172,82,131,94,224,19,221,77,182,76,166,213,168,120,102,90,110,234,137,5,154,197,148,197,54,107,209,189,173,83,232,134,155,251,146,116,31,17,255,107,26,184,254,101,106,126,229,145,237,214,5,139,207,166,38,200,2,122,57,145,104,135,89,17,125,173,176,224,239,8,118,29,203,216,146,235,251,94,85,162,63,255,51,133,97,83,180,223,212,227,166,197,134,143,72,254,245,136,237,74,20,161,182,157,73,234,180,160,6,107,50,141,54,57,73,148,89,250,101,182,160,105,205,94,145,81,70,166,71,17,127,25,203,153,3,201,211,212,96,235,59,231,198,235,255,44,224,91,170,100,46,224,122,208,164,97,57,247,72,91,69,29,237,238,214,71,72,222,86,122,111,233,10,84,26,146,87,32,96,26,58,27,255,150,230,6,105,162,226,168,7,99,12,51,160,153,7,107,164,148,184,18,233,253,27,15,108,4,191,141,58,205,75,246,244,8,50,223,214,15,190,114,197,195,245,87,164,211,232,158,178,20,16,184,178,90,99,100,255,184,149,72,201,107,251,117,1,60,29,234,122,73,64,53,195,125,91,50,45,140,145,99,16,249,15,30,36,31,231,184,226,41,74,254,103,134,31,57,144,162,189,87,41,18,50,193,158,68,163,253,175,126,176,70,163,134,181,190,164,107,37,146,134,149,86,167,77,219,74,120,238,203,122,237,28,172,92,76,127,121,127,241,43,189,221,38,129,159,184,130,23,155,236,93,213,229,228,203,145,151,86,47,148,94,60,60,201,50,202,207,119,195,170,68,58,145,226,191,96,152,68,129,200,236,104,240,16,12,57,169,89,5,41,25,221,45,5,247,248,178,107,128,252,81,230,244,176,57,149,175,192,236,34,244,152,205,235,12,90,190,207,223,244,236,176,125,72,97,238,187,242,128,233,94,185,88,54,69,211,94,165,128,50,142,207,171,119,155,133,54,73,127,97,67,143,137,58,80,99,207,250,223,64,164,165,70,226,101,64,20,68,121,37,192,107,250,244,21,243,159,113,105,145,174,58,244,40,116,52,93,191,38,37,26,119,243,79,155,25,197,116,45,233,66,162,127,168,135,68,255,192,9,137,174,140,149,160,176,161,194,38,179,57,27,226,45,102,175,127,65,165,111,59,50,99,83,133,216,183,236,238,202,17,16,79,240,55,6,164,81,76,112,119,165,147,74,191,70,252,199,189,25,151,157,252,62,163,246,11,253,188,3,140,63,43,82,180,46,5,97,49,75,193,129,158,82,217,252,138,52,253,33,147,154,245,207,19,2,198,89,247,253,238,149,116,9,227,110,193,105,82,82,143,174,168,244,119,185,221,42,63,203,187,85,42,52,115,79,66,215,240,150,162,170,62,25,197,86,225,25,197,214,114,130,158,153,25,69,145,91,173,49,242,77,207,59,13,90,158,13,10,71,178,163,174,13,33,57,93,86,70,191,206,92,34,78,43,175,101,231,1,218,149,34,124,255,254,62,243,175,121,76,209,83,7,106,76,149,184,37,253,47,112,89,150,57,146,232,102,137,212,208,177,125,204,218,136,26,38,185,135,178,91,225,220,21,45,61,86,152,222,116,152,213,230,186,176,112,116,195,154,119,99,251,17,236,2,158,164,184,205,154,182,95,106,86,16,20,92,238,159,77,184,181,157,180,154,180,157,44,208,193,217,19,87,22,76,47,213,113,35,245,240,156,65,143,28,122,239,116,177,99,225,52,32,17,9,206,108,126,114,33,174,207,25,39,253,207,152,8,40,38,184,90,188,184,255,241,64,14,249,47,131,165,82,193,175,10,35,147,12,59,255,120,240,5,90,16,69,152,124,206,133,41,147,194,135,216,210,20,46,88,207,63,172,217,122,78,79,29,56,124,158,199,254,246,223,59,75,171,129,140,114,69,75,95,130,247,11,100,113,190,237,133,149,168,249,230,207,179,89,104,184,74,49,165,180,227,153,254,60,248,97,64,22,6,234,192,225,68,252,151,222,255,1,225,182,9,10,132,110,21,150,115,126,247,0,166,181,156,253,187,173,148,228,69,170,72,153,242,32,41,242,173,124,74,230,241,247,206,58,235,33,241,160,186,204,126,215,238,146,251,183,171,188,59,69,179,143,72,160,82,73,185,7,134,185,63,130,136,98,89,110,34,193,63,67,167,133,251,97,74,243,106,219,124,127,254,159,217,15,35,34,69,99,225,6,176,255,38,65,115,145,52,252,67,121,195,19,168,246,12,166,77,175,181,67,206,202,94,95,178,150,63,140,220,223,143,98,130,251,57,205,74,199,148,224,63,70,76,70,29,31,163,236,232,94,226,31,153,193,167,188,15,68,32,154,14,95,173,226,160,113,226,127,28,153,17,137,20,189,247,63,17,200,15,213,153,31,41,218,22,51,94,170,176,120,162,177,151,13,137,118,88,10,73,143,102,92,74,3,255,31,116,171,220,161,91,165,58,191,233,63,232,110,29,167,94,206,238,92,118,58,242,118,203,200,184,199,153,54,146,75,75,24,143,225,179,41,62,149,173,127,173,238,205,29,111,190,177,82,187,254,47,245,246,208,47,151,71,174,61,225,185,162,161,17,190,255,230,35,138,185,96,249,152,21,127,186,195,167,208,191,157,104,139,145,58,80,99,171,12,176,97,248,95,226,79,147,164,139,146,242,190,121,123,241,69,81,190,0,149,150,26,233,109,8,2,214,166,174,34,75,163,71,74,145,3,209,203,135,251,26,144,16,159,6,53,72,179,255,77,158,15,128,161,213,232,183,59,45,222,113,188,255,60,128,214,106,137,61,38,108,35,237,248,207,45,92,99,127,66,78,145,18,145,236,127,70,22,145,255,242,195,127,9,39,224,108,170,203,229,121,76,222,31,95,82,198,243,107,19,243,236,253,21,180,152,31,81,254,235,111,59,245,103,220,109,151,240,222,171,124,252,255,44,253,53,218,248,196,89,189,155,154,227,238,200,229,107,26,150,63,143,109,42,176,198,125,242,47,82,180,64,117,206,182,80,250,26,16,246,191,236,87,152,100,19,75,76,23,181,248,245,34,205,59,124,124,68,188,237,0,148,175,192,245,200,181,245,127,1,241,35,205,23,34,105,94,101,213,239,228,255,197,217,123,36,174,199,239,99,170,212,150,112,119,185,184,209,34,252,80,157,217,145,92,188,223,147,131,232,232,189,52,166,190,187,39,253,21,155,62,58,34,145,34,91,18,10,37,76,253,136,96,186,251,237,219,136,214,202,189,163,163,132,12,136,199,218,94,220,234,181,91,11,98,22,111,54,3,33,55,201,103,200,9,107,92,23,97,152,63,0,248,116,239,105,138,33,199,150,54,82,214,179,177,181,126,4,38,205,226,108,82,48,238,239,32,202,29,18,96,53,224,45,112,159,200,241,168,173,44,199,126,177,188,194,235,61,48,7,166,0,181,179,36,191,129,142,28,113,222,60,94,0,110,195,148,47,179,175,170,207,151,122,32,24,189,94,182,66,11,64,43,72,206,137,206,64,44,96,201,123,255,116,213,85,231,9,45,53,82,181,178,36,91,144,101,173,109,34,239,3,136,168,91,17,115,1,123,126,82,198,152,148,99,121,108,118,217,59,254,56,69,94,8,91,75,66,36,202,234,81,77,215,231,5,221,173,220,76,198,172,49,129,26,191,91,139,63,33,107,2,222,73,31,18,125,160,76,73,31,102,129,174,51,192,22,149,166,109,155,196,139,160,59,55,50,110,119,19,226,20,125,124,142,1,25,59,194,121,183,125,169,115,73,213,68,236,158,157,127,203,185,0,244,220,34,173,157,132,252,24,134,10,150,97,44,42,88,66,16,49,81,218,168,52,20,240,163,59,110,177,109,249,96,180,105,122,79,129,242,27,230,108,72,180,26,123,40,38,184,223,193,207,180,96,15,64,13,71,8,121,100,79,42,176,46,37,179,216,78,226,132,53,153,234,123,205,220,253,165,206,35,198,56,134,127,219,96,16,39,53,30,80,140,161,142,163,148,139,139,41,38,116,101,239,193,136,239,80,200,27,31,231,123,18,251,88,219,254,247,129,210,193,16,39,253,91,224,54,239,180,157,61,50,233,124,17,60,92,226,53,148,115,22,89,211,125,108,248,72,157,20,253,171,77,7,255,215,37,163,7,251,21,37,200,2,20,137,27,224,147,87,50,107,156,134,4,213,188,48,21,208,236,108,184,31,234,56,151,255,33,127,134,160,169,234,63,254,131,25,111,28,0,30,237,27,10,16,102,202,80,175,120,31,194,158,197,181,134,16,47,193,77,176,231,43,116,185,66,200,180,34,22,101,113,197,60,182,118,21,196,206,64,218,185,230,97,109,13,185,150,187,201,83,124,75,217,137,198,100,147,7,88,65,101,30,196,71,232,52,58,192,97,15,32,209,110,96,116,129,190,186,73,218,25,135,67,204,225,185,30,52,55,189,61,130,148,141,207,57,94,218,220,147,36,58,18,236,217,135,172,149,218,93,172,230,199,69,203,95,145,239,246,143,153,64,247,99,32,20,202,215,213,183,129,75,17,233,135,58,206,234,47,166,254,170,248,90,187,229,47,36,143,162,14,127,89,115,203,181,221,108,163,183,34,181,230,250,60,4,23,111,230,194,100,64,142,29,82,30,123,194,211,115,173,89,121,224,46,75,89,160,131,95,39,200,84,225,36,70,30,116,18,70,243,34,225,134,134,204,108,148,234,229,143,104,184,154,46,164,249,36,200,159,187,150,174,26,228,12,246,208,118,240,210,116,63,246,252,245,169,12,96,71,35,187,18,178,61,111,251,237,39,28,237,247,236,189,203,242,49,44,83,112,136,157,220,210,49,221,251,11,58,226,226,247,130,19,55,54,252,83,98,68,188,66,110,36,61,154,151,198,68,95,247,239,61,81,69,24,209,168,13,57,48,26,96,126,20,232,62,159,63,58,191,182,230,241,204,209,189,85,116,42,30,45,236,113,86,222,236,37,94,126,252,211,249,245,73,77,9,124,52,32,171,164,214,53,108,74,123,99,189,36,84,11,224,93,201,177,67,2,20,192,253,137,93,13,0,105,57,67,7,182,97,161,62,90,206,175,71,178,45,216,238,233,73,213,47,147,254,112,195,29,206,244,48,19,17,127,49,152,237,91,105,154,59,23,144,189,115,129,34,129,68,146,123,23,40,146,161,142,158,171,122,255,141,70,213,251,245,34,55,37,205,9,61,193,203,27,150,169,18,234,175,250,159,132,116,162,141,175,198,98,79,160,227,209,210,231,235,217,202,94,238,201,249,206,65,114,220,98,111,232,105,161,220,39,207,97,18,47,123,177,176,85,25,244,194,102,169,202,73,12,213,27,96,223,172,224,4,11,137,85,156,216,46,15,68,137,123,124,11,242,20,251,253,9,88,30,137,75,113,191,242,151,120,173,54,77,25,119,220,76,115,199,205,69,108,27,247,108,251,37,16,5,226,203,103,45,32,49,53,120,118,197,129,171,115,244,110,118,70,231,218,254,52,141,230,124,165,67,236,9,132,155,125,160,180,156,228,235,74,55,84,58,130,96,242,205,103,216,15,61,230,85,110,246,216,118,38,197,52,245,174,118,68,87,95,14,168,148,52,100,2,230,12,253,17,218,186,132,121,4,252,154,251,181,71,95,237,254,225,194,136,160,216,190,75,151,129,192,13,186,63,51,139,67,93,63,41,247,187,163,68,236,187,112,28,227,169,197,33,247,87,78,64,70,65,173,78,32,235,42,230,42,26,119,164,29,54,199,252,238,119,91,216,210,128,208,181,26,49,204,55,6,149,50,148,45,112,185,219,216,136,188,67,214,65,146,78,61,79,54,154,70,6,168,158,236,201,156,66,30,155,15,120,199,135,79,155,25,136,255,135,177,120,27,224,225,24,90,250,247,134,102,69,106,130,7,42,180,0,139,209,199,194,239,99,147,148,95,115,62,78,62,6,213,157,93,198,121,16,159,6,89,214,187,38,10,62,48,19,109,171,142,67,167,155,158,249,116,81,104,244,55,199,200,94,178,9,235,216,227,198,215,64,161,197,1,126,219,47,199,57,64,129,93,122,41,160,52,31,69,119,30,130,86,155,127,223,135,108,59,32,70,102,25,160,146,3,186,90,126,81,176,199,121,137,199,63,5,119,159,74,193,252,153,48,49,199,26,255,39,160,52,161,68,220,2,92,18,120,237,24,138,77,104,169,145,180,131,37,61,32,226,175,240,95,222,137,134,177,68,63,76,233,49,194,114,252,251,252,36,245,16,197,188,56,103,244,195,215,132,46,154,140,95,47,214,176,27,185,118,91,179,67,104,159,121,154,207,231,188,15,173,170,230,32,9,175,107,11,253,68,141,95,94,175,100,81,167,112,218,221,184,65,102,32,182,58,140,146,132,37,243,41,249,60,18,144,254,202,82,116,100,190,233,164,16,186,115,147,190,2,197,185,21,172,141,186,245,23,184,143,38,12,72,144,157,50,171,245,68,197,22,56,219,163,93,141,63,123,68,141,186,254,190,162,65,169,26,21,111,155,15,165,193,237,115,6,107,238,63,18,199,91,132,37,138,135,123,96,199,172,73,145,221,86,131,46,67,177,30,17,53,208,187,229,23,38,45,247,188,250,147,206,189,101,45,164,56,199,92,13,210,4,233,105,211,119,88,172,152,138,97,123,24,225,133,67,83,88,220,175,183,63,249,250,217,51,193,70,120,238,160,113,18,144,234,15,85,231,65,33,42,183,143,194,120,249,176,55,178,95,176,1,47,163,163,177,124,21,152,152,239,135,100,39,96,142,5,233,39,199,149,163,134,73,150,226,13,163,231,232,21,227,109,40,220,179,74,4,42,223,228,132,83,4,255,40,170,114,244,251,231,56,185,170,186,158,232,99,56,178,117,210,129,241,96,3,138,160,102,187,49,135,60,73,12,28,35,172,110,222,195,177,228,215,57,38,215,104,70,140,1,128,222,171,117,127,170,85,190,157,68,223,147,33,155,54,253,103,122,248,240,98,232,53,127,254,158,221,99,48,224,203,80,89,20,100,227,158,183,62,19,28,135,122,64,36,42,60,82,189,239,191,8,144,156,184,210,215,184,19,15,143,16,159,6,137,200,241,179,36,220,207,146,130,65,114,13,171,64,103,193,144,128,206,67,80,254,42,71,223,185,46,167,148,81,69,198,182,163,77,120,104,149,200,80,72,173,139,194,253,234,188,121,232,179,227,238,179,242,208,190,31,219,221,137,243,2,178,70,148,173,129,190,57,217,76,59,207,201,194,33,137,100,59,36,240,249,120,45,81,173,219,49,112,55,44,100,225,183,243,30,240,23,46,161,120,188,155,242,108,216,3,177,181,122,9,131,138,172,159,125,113,186,215,23,248,133,207,128,24,225,168,97,146,5,212,95,116,186,92,34,44,181,24,239,157,71,68,137,154,125,222,65,95,197,247,88,220,16,141,132,224,232,253,124,91,52,219,150,244,25,2,64,238,84,39,112,152,140,205,115,123,85,95,50,3,213,158,32,246,41,36,141,24,42,206,143,242,234,53,138,102,140,162,35,50,92,72,113,231,88,229,70,42,172,21,159,96,191,99,233,13,202,147,159,184,207,176,195,229,14,56,171,241,106,136,12,117,26,96,47,222,89,94,2,28,196,241,171,169,132,157,108,238,45,163,132,50,12,238,66,6,56,28,105,161,143,228,220,123,21,109,92,200,232,201,243,188,194,59,215,70,191,83,163,44,223,21,211,8,239,181,40,51,98,182,244,32,155,151,22,61,72,113,163,137,135,233,213,245,82,55,152,27,173,183,194,123,87,34,76,159,155,184,243,76,205,64,88,118,11,22,44,69,135,127,90,39,230,236,255,66,244,131,7,225,210,11,192,202,39,77,63,124,248,184,110,133,246,109,177,129,104,3,204,61,83,101,11,22,106,51,44,202,89,163,248,160,62,121,252,87,97,234,33,103,60,196,119,145,40,76,146,8,113,81,233,38,93,224,187,183,11,45,18,173,70,31,202,79,233,194,100,43,5,143,123,89,156,106,130,132,149,186,208,145,190,224,189,125,168,238,66,27,220,164,23,74,48,200,167,116,133,0,24,8,184,161,255,73,198,170,197,124,104,238,33,75,166,225,173,146,90,238,176,218,139,165,222,217,46,22,29,82,137,67,16,243,102,226,241,254,149,42,182,58,59,89,172,214,141,98,224,249,19,3,73,140,201,146,164,94,214,167,39,58,183,99,96,193,183,55,84,23,46,214,214,77,176,7,65,247,25,175,112,254,137,0,70,124,232,131,113,52,40,129,24,17,119,220,75,125,199,189,133,76,27,90,127,113,239,46,87,123,15,48,99,125,125,111,161,50,50,137,116,166,162,29,109,88,137,212,244,153,69,211,10,10,139,0,199,70,55,230,137,11,59,234,139,29,134,246,88,12,58,77,53,98,174,162,146,132,242,219,83,99,207,53,78,209,29,156,120,19,2,217,78,64,45,214,225,4,204,254,199,85,126,222,158,157,39,24,176,207,134,236,9,174,214,181,77,17,33,254,83,44,81,161,182,93,27,102,43,78,223,239,29,144,52,37,65,196,51,15,149,244,128,44,196,20,6,200,73,162,88,6,249,97,74,243,107,225,245,134,60,164,7,52,203,23,207,188,147,196,201,40,79,51,10,210,45,188,77,134,222,152,5,125,180,194,122,206,47,86,214,93,249,85,254,249,81,145,242,86,70,198,183,140,163,186,13,41,145,51,139,151,204,171,45,159,150,188,122,222,191,193,164,28,223,171,161,37,249,104,144,151,189,145,103,4,153,128,185,107,46,211,142,128,5,115,111,178,231,27,59,37,190,203,60,248,60,58,226,98,223,67,106,248,83,245,139,24,204,86,95,43,231,46,62,74,75,62,206,209,43,66,219,144,185,119,246,239,184,199,63,188,158,143,229,96,49,70,241,92,35,120,149,141,91,56,27,171,229,118,134,158,155,231,135,43,90,44,121,113,8,201,125,198,148,112,8,221,219,250,121,202,197,145,16,168,32,68,79,106,113,154,232,80,72,24,154,216,150,7,12,27,227,20,203,207,214,13,72,184,82,72,127,111,140,134,156,95,75,105,39,102,9,108,128,125,197,80,132,62,22,77,42,154,135,203,166,36,138,178,213,200,9,255,21,38,182,105,61,150,186,150,44,30,62,39,163,185,227,164,117,47,177,71,254,214,65,145,253,210,133,250,155,250,223,34,130,6,17,152,145,144,144,97,79,218,121,54,206,52,229,179,72,144,208,127,124,214,38,110,38,115,146,205,230,189,74,38,101,49,36,170,151,50,0,91,193,91,162,56,125,137,215,26,238,133,222,214,182,221,222,73,233,251,88,211,232,170,13,7,141,1,103,135,41,226,29,97,73,135,209,1,206,84,116,25,224,136,238,163,57,188,253,48,242,21,94,38,81,204,3,132,190,163,30,183,168,117,125,97,165,23,193,187,79,179,122,215,142,62,250,159,226,34,226,21,202,33,157,216,219,178,111,170,120,224,35,254,45,168,123,6,196,218,122,122,212,212,196,26,63,117,177,243,242,173,37,70,241,123,47,164,227,128,133,87,47,53,65,217,141,156,29,222,248,8,139,47,218,198,194,139,198,226,156,0,223,54,171,110,19,59,169,98,246,190,244,219,72,9,51,220,233,26,212,106,128,129,68,3,204,178,28,254,30,212,73,169,254,16,191,89,16,37,26,113,113,184,204,103,243,88,200,50,255,184,24,99,235,237,92,47,170,208,173,37,231,255,198,195,48,145,184,214,232,233,162,201,236,205,65,39,78,217,73,151,30,215,63,101,195,218,136,214,162,99,111,198,130,170,211,3,86,187,146,19,242,13,40,100,145,113,163,37,50,72,195,18,237,49,225,228,134,234,194,234,92,125,220,228,149,163,156,48,75,96,147,189,187,212,246,141,49,83,252,28,114,92,28,122,38,40,98,212,43,174,3,141,6,146,114,155,98,49,10,127,231,59,134,53,247,146,246,65,95,69,249,1,250,218,150,56,32,9,15,185,123,52,130,167,34,8,100,195,110,0,187,67,148,252,29,162,254,19,62,150,251,36,93,200,219,218,175,199,45,63,123,187,120,197,170,87,252,178,150,161,139,198,176,15,163,122,76,153,93,18,67,154,145,41,199,252,235,74,146,89,7,143,198,49,47,245,27,138,24,41,119,2,80,165,64,254,43,22,31,169,38,41,112,60,45,90,83,236,98,71,7,69,9,180,134,136,253,199,241,83,110,113,106,30,129,120,190,233,192,101,108,134,147,172,252,196,19,31,178,234,112,132,163,53,19,62,78,196,123,122,228,99,210,160,4,10,226,36,197,162,134,73,178,227,15,207,110,233,149,16,109,40,222,207,171,18,109,252,44,48,249,208,220,26,149,23,27,75,246,39,94,112,230,227,220,219,84,255,224,208,216,115,101,71,22,86,185,249,207,50,154,144,179,58,139,93,202,110,91,202,213,120,234,111,191,157,208,53,176,13,193,135,109,218,59,36,192,26,12,129,71,119,154,167,122,26,94,225,114,202,58,224,195,56,244,16,206,120,16,65,240,246,16,55,111,199,255,247,200,138,142,150,247,94,180,132,23,146,133,163,115,109,223,48,134,197,79,62,58,22,34,211,167,250,108,121,171,224,212,226,170,231,49,102,175,6,95,254,122,177,55,169,90,183,141,24,187,146,5,122,190,110,234,137,107,26,121,184,217,56,3,116,53,86,32,247,34,133,131,245,45,144,127,28,254,229,72,41,196,238,194,230,97,208,9,20,72,138,50,91,208,247,156,109,149,123,86,124,129,252,110,81,167,55,252,79,140,224,65,253,79,4,243,99,195,219,118,23,237,157,170,30,97,238,216,144,74,10,31,194,181,55,198,11,152,55,15,76,215,137,221,186,172,56,151,37,172,69,79,26,253,18,91,94,156,31,55,100,169,173,90,66,239,72,181,187,44,213,225,118,134,143,147,79,165,114,231,74,36,129,70,158,13,176,166,37,73,208,242,219,96,55,6,222,239,112,69,121,171,11,253,191,44,128,251,238,201,12,238,101,28,123,80,175,242,159,117,183,134,122,198,72,213,38,90,98,209,14,123,160,254,166,30,247,216,85,18,190,47,57,109,35,248,123,211,205,190,192,80,135,148,147,218,252,186,209,230,38,230,22,7,198,163,5,132,109,183,113,91,69,143,189,8,47,15,196,32,195,97,180,33,123,247,110,181,190,59,247,7,203,2,2,47,22,137,89,221,147,16,127,180,208,68,240,212,208,201,52,157,108,175,109,137,163,166,124,156,239,137,206,237,89,159,204,20,149,87,240,206,20,92,35,77,191,221,131,250,30,191,26,114,8,0,21,24,194,167,165,171,87,193,219,247,229,10,106,188,227,21,206,24,31,8,59,43,45,53,82,102,128,31,166,116,230,215,207,137,138,247,94,30,131,255,229,164,139,2,123,247,56,147,106,49,245,131,208,145,0,137,160,8,253,45,6,187,96,167,42,27,196,252,27,90,59,142,49,83,46,206,42,227,153,106,127,26,143,26,10,111,0,124,36,244,172,232,58,93,198,246,60,7,211,196,130,60,254,110,42,107,193,113,101,36,134,130,190,37,123,118,33,151,0,46,123,47,166,206,24,165,127,196,122,104,94,173,68,243,60,121,140,247,189,50,76,236,94,250,64,139,68,59,44,124,103,31,225,93,197,250,191,34,186,63,95,119,143,240,150,73,231,73,146,24,223,178,253,135,69,85,113,161,11,22,13,91,234,23,111,96,215,69,10,121,8,216,21,103,218,56,206,9,154,52,186,121,73,37,47,50,230,177,114,53,4,80,104,218,18,89,19,34,126,230,25,65,114,223,254,40,149,11,140,124,29,255,249,5,223,155,199,127,164,106,23,20,7,107,243,103,128,224,141,78,203,52,245,223,146,108,25,74,5,146,103,121,240,119,90,68,108,187,83,31,171,72,164,83,66,68,188,66,126,36,207,241,252,73,75,217,107,60,196,135,194,48,76,73,112,176,44,148,165,123,44,66,167,58,24,45,148,224,11,164,123,230,99,68,61,243,80,100,129,164,204,160,169,65,178,162,70,86,165,135,18,245,250,194,84,169,56,13,62,91,240,252,186,63,243,167,202,238,53,110,44,249,113,70,232,178,164,227,234,16,49,126,41,253,172,54,121,49,244,135,233,246,141,113,122,24,155,233,103,48,96,63,166,233,145,167,122,87,217,95,134,138,144,60,143,133,188,122,168,37,155,167,73,42,175,29,37,51,108,176,33,209,106,176,221,17,226,107,75,233,235,135,130,16,43,202,135,225,69,103,132,88,150,143,151,17,61,23,31,240,179,158,173,24,41,40,171,81,238,23,116,167,159,174,123,171,168,110,89,104,163,211,177,147,224,4,134,116,7,183,117,131,105,133,86,105,132,153,49,51,115,100,111,122,164,32,51,150,95,163,221,3,95,222,41,12,228,91,170,159,178,231,102,35,240,147,155,135,226,36,51,193,178,157,43,178,111,193,238,153,248,7,97,141,238,123,144,171,181,118,183,237,50,77,60,147,253,162,141,23,39,85,168,253,42,133,231,62,57,29,166,68,52,74,149,65,198,210,89,95,46,255,68,144,37,129,54,132,230,62,40,81,64,72,122,72,99,219,136,166,46,120,222,17,228,211,76,230,92,201,117,33,17,57,132,246,146,49,97,52,15,83,220,156,230,244,149,36,102,151,112,179,253,161,225,155,228,44,150,254,36,23,68,40,214,26,211,244,239,79,116,26,150,60,143,158,54,125,181,44,107,57,163,159,92,45,191,232,78,230,246,41,7,133,19,204,48,130,206,149,39,83,122,166,38,230,50,156,46,85,109,240,69,47,40,166,93,210,246,150,110,133,147,117,255,6,90,106,128,123,236,22,8,115,64,230,33,47,92,174,29,114,192,57,128,230,135,221,233,199,199,119,220,16,162,167,69,249,192,13,42,173,5,2,11,146,129,61,31,73,141,133,194,220,114,177,106,109,91,253,81,160,79,19,101,226,117,146,55,10,248,231,71,190,6,78,117,165,140,161,209,225,64,180,201,65,71,46,185,56,77,92,237,243,219,229,105,10,212,3,212,138,221,235,187,84,162,31,19,223,122,95,40,94,44,3,97,22,78,131,19,83,174,144,69,28,155,203,102,108,123,227,177,243,225,35,226,82,22,102,120,59,206,188,41,19,249,137,12,18,74,236,151,227,114,166,197,26,9,167,254,25,150,43,117,139,235,130,159,176,124,224,174,17,48,118,222,173,0,186,25,70,149,3,61,121,6,254,104,225,38,118,18,51,32,209,77,238,251,235,181,30,219,20,156,175,28,104,144,108,91,18,29,178,43,244,243,30,145,133,184,199,10,40,195,58,93,20,42,157,70,10,247,219,67,132,228,171,147,217,181,68,100,68,17,254,127,79,62,21,25,227,84,113,96,178,76,135,106,22,183,39,19,210,47,194,207,178,154,222,155,234,82,32,205,167,38,60,103,227,104,255,109,239,160,221,135,92,178,98,15,184,244,7,170,197,117,81,82,134,2,54,82,93,223,34,67,113,163,79,12,68,86,151,206,134,210,15,162,214,176,221,158,10,170,231,59,203,144,75,240,49,123,140,82,90,2,111,47,9,106,90,165,161,251,23,100,101,53,250,48,215,180,45,243,171,10,245,131,128,177,152,106,23,193,217,249,27,246,22,194,85,103,3,120,20,43,112,240,171,147,178,1,180,46,16,114,57,99,43,115,107,190,237,21,166,200,166,255,18,187,214,208,78,140,57,211,186,234,236,114,191,144,0,184,68,11,127,250,202,87,141,122,66,250,214,170,24,114,235,107,230,67,118,211,230,37,119,59,103,123,217,108,179,124,98,214,37,23,55,107,145,97,63,103,30,11,112,204,166,112,155,198,9,240,89,5,238,12,92,206,225,247,61,95,178,188,181,83,6,21,28,76,209,150,43,142,179,144,235,185,90,235,13,83,73,50,29,220,20,143,30,137,124,176,228,44,131,51,167,244,169,224,64,153,103,207,15,129,223,123,151,34,124,105,31,234,242,133,140,203,151,142,87,236,74,181,212,19,254,34,247,95,217,35,53,5,95,56,168,183,212,19,147,224,225,250,127,102,162,14,212,24,208,249,196,195,124,95,7,102,65,17,178,45,88,131,154,71,173,140,229,121,95,17,31,249,187,181,7,13,77,58,5,16,251,135,109,141,117,8,109,134,114,67,201,209,52,176,89,18,163,20,56,150,195,21,196,94,44,83,219,6,21,161,40,168,96,124,120,3,191,66,91,179,153,191,250,113,24,187,174,84,153,85,52,253,18,159,171,101,50,194,227,106,189,253,18,239,181,18,153,131,145,199,202,211,189,218,14,173,132,60,0,209,216,88,239,81,91,182,225,134,66,242,138,214,74,216,99,141,140,130,64,106,230,155,224,23,218,48,227,238,152,202,147,181,174,245,233,141,196,239,177,159,250,167,185,115,211,8,201,147,168,223,100,152,192,120,43,33,134,179,204,140,167,147,66,50,179,70,250,27,84,226,158,63,85,73,117,44,210,215,186,162,30,73,188,70,127,42,96,7,39,232,138,173,58,177,238,147,154,77,83,183,78,221,118,16,65,134,155,251,140,72,52,225,62,127,18,185,231,66,72,196,95,93,14,175,185,18,181,12,72,167,185,201,73,153,50,126,105,208,149,211,252,80,223,64,200,228,205,100,20,14,12,172,249,227,247,72,136,49,245,219,227,175,30,63,177,145,251,194,139,123,60,85,224,22,18,197,26,251,87,134,79,131,148,49,15,110,212,84,131,174,118,141,195,185,25,145,86,65,76,107,57,113,103,61,122,106,93,142,31,18,145,122,174,53,27,234,193,97,98,33,92,208,5,178,170,194,166,107,176,187,208,242,34,65,96,208,94,232,243,13,3,160,154,128,220,183,21,58,105,109,66,165,143,79,1,174,78,209,54,85,103,148,89,100,140,170,165,78,253,252,181,54,77,96,215,196,214,29,250,237,2,49,162,14,32,192,9,58,150,3,41,123,110,167,117,237,49,139,7,125,170,200,1,88,243,192,199,246,235,190,246,131,164,49,15,233,47,15,133,21,29,11,15,196,108,15,245,120,25,48,138,215,131,141,250,110,214,100,68,12,101,63,38,176,109,109,103,104,255,210,231,0,34,95,51,194,45,97,199,251,40,144,92,235,18,40,179,172,38,49,95,165,133,43,212,236,171,159,94,194,193,208,89,65,244,189,1,120,145,174,221,184,224,186,124,4,113,247,233,23,130,157,253,217,149,62,223,29,147,60,65,44,197,221,37,7,231,25,220,151,14,85,144,16,179,11,67,218,58,178,189,213,19,198,235,84,93,144,177,11,76,206,4,253,79,81,64,76,170,200,202,163,43,94,182,167,178,8,208,5,247,120,76,128,226,32,145,36,99,20,30,13,101,49,171,24,82,0,30,42,116,35,124,83,99,212,188,175,228,231,119,112,70,62,201,175,66,122,190,208,94,145,244,234,75,235,195,234,115,116,182,153,165,67,207,209,67,208,218,17,215,227,1,227,116,187,198,72,240,238,4,83,36,157,77,199,182,31,44,140,11,218,103,132,80,74,238,247,138,180,82,76,253,29,1,195,147,0,226,171,4,76,138,200,158,217,180,170,35,177,154,109,252,62,161,31,97,84,43,243,23,70,158,194,87,50,232,253,116,170,147,192,227,108,205,141,35,204,27,228,215,154,24,49,189,67,117,61,68,146,173,69,208,51,153,55,182,16,147,142,66,210,199,55,220,157,86,153,64,131,141,31,170,157,17,142,53,195,48,61,86,96,98,38,247,138,174,47,97,67,243,222,210,117,133,139,136,250,246,160,143,150,232,1,240,243,158,89,150,238,208,223,170,240,29,83,248,160,40,224,249,72,101,156,247,61,219,158,94,233,211,223,155,234,105,144,136,130,56,75,202,253,157,9,210,212,170,38,78,101,9,155,254,143,173,141,15,5,84,151,187,158,11,65,70,215,75,48,24,199,48,31,61,141,77,168,38,236,206,50,170,40,218,10,226,22,243,230,16,164,23,179,201,198,187,80,124,79,210,85,196,180,137,239,144,200,228,151,198,210,219,113,248,19,96,96,115,198,89,103,175,130,93,192,140,215,65,16,17,12,147,35,49,26,189,184,62,209,116,159,32,5,183,3,54,56,21,235,232,199,76,22,197,156,216,183,179,53,55,46,3,100,223,123,75,7,111,224,248,22,69,253,174,82,143,57,35,68,52,132,189,108,233,93,199,176,26,14,37,173,89,33,158,155,254,81,144,181,213,51,26,74,179,46,185,181,177,229,128,149,4,112,20,92,155,51,210,7,31,29,103,188,231,194,246,45,137,73,158,3,250,80,148,135,116,100,218,196,12,178,197,220,206,110,81,149,118,58,189,53,153,139,12,228,229,148,47,130,118,50,240,111,76,1,245,33,115,150,240,49,3,0,151,44,86,114,17,10,217,67,241,251,234,81,187,72,113,121,236,45,231,201,125,48,55,15,244,179,101,154,243,203,165,198,43,20,71,226,65,157,48,204,100,126,160,117,237,23,173,76,174,220,99,61,215,59,124,46,209,198,228,249,19,116,59,92,140,149,52,43,167,195,61,5,112,31,218,140,238,168,29,196,243,53,143,207,92,23,77,220,165,235,161,29,222,19,8,76,195,11,188,61,188,158,163,67,204,44,227,107,215,79,199,190,249,21,144,47,170,130,129,23,59,161,2,219,59,76,44,89,235,187,214,99,118,71,38,224,133,93,235,97,222,216,57,51,42,96,80,197,240,80,94,178,190,135,139,190,201,8,44,71,112,135,234,124,94,251,162,71,65,38,65,10,173,222,111,254,113,186,181,77,243,205,187,124,77,37,146,71,21,36,217,62,163,139,238,215,114,94,123,213,82,98,213,176,190,231,86,202,236,181,241,165,205,139,155,175,159,248,216,36,193,147,72,178,107,117,12,189,31,159,100,87,101,137,127,172,38,122,77,246,206,170,20,100,65,200,89,105,152,184,52,246,94,92,195,109,116,136,226,165,192,218,145,216,83,233,154,223,137,83,233,10,1,217,112,166,189,77,72,182,215,41,30,153,196,62,239,11,45,245,92,246,202,43,173,26,177,215,38,62,176,157,130,139,223,200,240,26,26,187,150,247,250,214,160,170,210,202,46,145,156,167,22,160,147,94,229,139,221,47,102,7,99,177,139,181,177,0,114,203,133,134,137,57,218,72,112,45,67,178,222,162,192,172,163,126,241,222,162,184,149,154,67,127,150,199,170,230,237,105,164,186,118,11,214,169,242,180,35,91,233,123,58,5,204,218,173,44,247,14,56,163,74,134,57,242,228,92,199,164,158,157,113,58,65,113,83,156,13,103,119,227,81,147,45,167,4,52,21,203,243,80,113,47,56,233,131,50,7,40,222,166,250,192,86,224,214,192,233,49,6,167,224,171,31,81,207,57,4,163,47,126,85,169,83,151,115,78,167,151,183,4,57,63,211,84,239,123,3,55,213,249,81,45,56,207,183,193,214,35,163,217,129,209,95,90,13,15,112,232,232,74,142,1,15,160,216,235,142,82,129,19,151,4,250,227,131,100,4,12,210,186,123,78,21,225,21,234,128,139,26,240,100,49,231,244,48,205,209,12,18,148,184,154,161,205,25,12,22,248,249,136,100,55,52,204,144,199,146,109,23,132,136,214,114,189,27,89,24,107,182,159,144,67,53,221,109,14,42,137,245,141,228,176,136,204,109,34,107,227,154,46,213,199,137,157,209,130,86,205,151,55,93,101,52,223,172,86,93,220,244,13,233,199,102,85,77,71,20,151,249,11,212,123,140,62,70,180,19,252,4,220,244,7,170,150,131,134,0,183,164,83,79,203,48,12,8,100,150,188,166,136,13,221,185,183,141,22,39,117,221,100,244,223,181,249,14,156,3,206,174,218,47,54,182,178,189,102,85,42,169,102,23,42,217,202,45,141,188,47,194,197,61,225,153,2,211,115,11,101,53,189,187,86,110,133,208,218,254,108,15,249,85,24,104,227,226,8,28,115,28,51,14,152,35,180,250,187,28,239,191,173,238,33,72,243,160,167,137,17,169,152,182,147,43,217,101,209,9,252,63,211,82,7,106,168,190,10,229,185,215,99,92,252,168,246,17,188,170,22,36,61,215,80,139,103,35,99,47,252,118,70,83,159,148,197,238,104,128,194,193,246,65,215,121,2,144,53,220,45,22,185,32,18,77,135,101,7,3,25,242,91,122,118,166,207,111,129,244,217,188,203,55,103,138,253,155,53,197,240,96,38,170,90,237,24,137,186,48,185,96,248,204,254,220,100,177,27,39,25,228,194,202,245,2,13,84,136,78,86,113,33,239,122,152,84,75,120,163,224,45,60,31,35,177,237,117,49,48,101,68,228,200,119,106,93,185,225,234,16,163,226,115,179,163,112,209,104,12,252,48,244,203,175,205,122,131,103,3,186,107,101,103,222,13,187,240,214,175,91,194,151,8,127,203,1,175,227,206,61,200,72,136,253,1,92,114,204,84,48,33,237,243,184,85,213,153,201,112,26,52,21,61,252,1,204,73,129,57,103,217,126,66,21,155,93,166,170,218,140,123,47,103,31,250,91,238,37,249,186,152,22,91,108,81,134,139,87,143,112,193,47,210,99,76,49,233,15,233,111,47,42,76,117,12,58,57,132,14,132,80,101,245,206,250,65,8,140,155,83,39,142,217,23,197,217,191,234,4,198,215,182,248,206,178,122,46,140,60,31,137,110,38,158,89,7,79,76,149,140,194,183,156,212,93,115,145,77,11,45,231,50,47,42,74,221,166,23,124,93,166,91,4,62,158,11,174,132,171,64,207,186,138,75,46,173,125,246,135,4,23,204,160,201,186,248,253,49,149,115,101,32,90,71,5,185,158,183,110,59,84,251,63,1,134,166,202,236,32,116,198,179,226,185,37,179,108,111,147,2,40,62,248,252,138,174,232,165,240,235,125,29,35,47,228,241,49,42,235,28,57,18,167,103,27,16,237,95,202,153,206,175,170,129,131,174,27,98,117,184,52,191,138,195,125,65,95,197,70,120,46,149,40,33,172,31,94,30,15,29,192,179,5,141,140,129,87,11,14,2,31,9,223,188,108,124,227,5,174,145,137,17,107,115,93,196,176,65,105,16,179,176,206,242,217,167,185,61,40,247,253,216,174,65,149,149,233,200,71,194,163,239,152,70,180,95,152,48,84,157,164,65,69,163,93,4,231,54,150,159,17,46,32,183,114,91,112,100,255,240,13,85,232,102,43,90,231,70,176,206,245,6,230,43,100,44,175,205,44,103,0,80,106,53,198,41,174,18,133,193,4,237,56,53,99,207,67,149,123,192,187,19,125,216,176,107,180,154,190,172,91,25,17,177,122,104,95,125,193,47,92,176,53,77,221,0,135,215,172,35,91,153,245,86,202,220,2,18,198,108,175,85,9,17,79,191,55,217,1,240,251,37,192,176,165,144,142,19,19,92,149,245,227,175,170,141,191,228,14,172,60,88,195,227,190,40,72,143,228,0,47,111,84,226,71,197,219,126,142,114,106,156,149,201,0,234,45,248,187,213,233,139,59,17,57,253,73,37,142,202,234,22,203,110,234,152,75,46,146,246,10,10,203,146,223,134,246,215,58,127,48,252,248,92,209,102,63,158,122,83,197,231,235,28,131,143,214,132,248,7,158,212,46,58,245,48,30,202,237,155,15,142,105,172,210,128,53,173,231,244,169,174,25,110,47,64,10,93,140,149,219,120,160,170,91,28,235,36,196,189,111,178,113,148,191,178,124,118,65,92,246,144,218,97,32,56,123,168,74,211,8,152,105,172,95,75,185,112,80,55,198,249,51,75,220,171,97,105,79,215,162,18,30,147,30,244,9,241,100,103,116,240,178,127,245,76,93,220,242,201,97,75,176,15,55,164,10,245,18,105,124,230,234,199,218,1,147,23,240,73,215,151,189,133,236,27,54,83,219,159,120,116,161,115,19,41,16,202,141,1,134,16,82,108,143,228,138,46,69,133,171,198,16,92,28,138,23,143,158,72,60,141,245,153,212,220,204,38,226,222,111,167,57,154,102,48,203,142,122,249,225,102,49,225,44,42,181,25,188,219,119,241,244,245,151,117,49,126,118,128,233,19,16,248,59,244,180,162,121,127,175,92,254,27,79,136,175,122,55,145,92,90,150,199,46,158,232,230,176,184,205,243,104,169,162,47,194,118,185,45,215,179,49,162,144,39,174,93,229,216,78,198,26,29,157,201,232,39,10,80,42,224,85,75,166,207,233,136,175,244,209,60,108,209,125,67,238,118,101,80,83,61,170,155,75,71,146,66,17,142,161,14,29,194,190,2,177,91,11,189,46,148,189,53,35,149,17,29,134,37,248,246,198,102,115,181,117,69,147,217,24,119,199,252,56,153,142,61,131,146,146,245,173,113,27,91,207,95,57,12,156,123,9,224,214,246,103,203,215,84,249,58,5,69,83,240,71,244,132,4,190,75,166,224,245,76,204,132,207,25,239,151,111,101,134,112,37,163,2,175,224,155,123,133,177,38,152,189,149,30,217,132,115,162,118,45,232,185,115,18,23,19,58,92,206,201,187,192,121,247,159,61,62,45,198,240,28,238,176,79,8,252,103,102,143,229,99,174,126,149,93,143,9,139,149,8,233,188,29,25,34,45,200,141,25,20,163,244,112,203,53,100,24,122,3,223,30,201,61,104,210,6,90,164,100,193,27,89,161,88,215,55,5,212,231,56,62,71,20,183,99,51,5,146,33,59,237,109,156,166,197,66,71,195,224,216,23,239,59,156,92,62,105,136,30,80,181,29,206,150,194,191,66,104,202,75,239,85,97,176,164,3,60,165,225,68,41,236,161,193,178,23,165,119,237,168,18,20,35,39,137,98,153,224,247,26,117,226,99,51,179,206,131,214,81,246,75,40,144,232,9,71,113,95,78,40,186,78,101,242,208,74,42,15,147,174,232,235,214,62,117,200,16,103,9,149,20,81,15,97,67,181,95,214,110,32,74,19,105,210,111,161,81,87,242,226,218,208,202,203,91,202,53,225,60,92,177,173,91,253,144,110,28,211,34,231,120,190,246,61,138,232,117,231,222,164,192,124,191,203,183,160,81,49,62,130,78,103,23,165,70,108,54,12,95,135,81,97,215,86,219,244,15,171,190,72,50,184,243,230,41,89,151,162,100,246,11,153,182,235,117,27,159,65,173,217,105,232,181,75,177,177,53,249,41,250,51,125,35,195,92,35,131,34,239,191,248,240,159,42,227,152,64,22,155,111,167,93,27,125,151,22,129,118,21,226,215,199,205,44,31,233,76,228,103,141,124,225,250,162,55,181,91,210,2,167,14,115,209,58,87,108,155,1,105,91,253,224,33,81,184,180,0,165,124,32,94,251,201,238,243,186,74,95,70,19,93,233,208,191,222,5,240,130,62,77,189,17,66,80,199,44,149,217,124,49,234,228,58,209,9,186,124,41,78,133,106,15,227,242,220,255,1,87,63,110,104,120,131,138,183,147,16,92,236,6,229,92,229,183,154,97,176,3,68,219,73,155,102,123,234,163,149,55,232,151,192,121,38,159,20,167,103,121,174,251,146,65,6,201,226,34,241,135,135,29,193,217,190,118,161,148,46,241,183,114,237,57,13,230,10,235,151,44,134,118,242,130,102,75,30,239,194,110,123,133,19,251,0,235,3,83,199,13,13,83,232,105,158,77,143,163,203,107,114,141,189,227,125,54,174,11,42,118,183,133,245,223,39,33,26,198,132,132,99,105,170,211,201,215,145,11,54,123,14,125,156,59,170,73,105,6,92,81,120,237,142,120,149,34,202,243,119,193,159,241,0,133,47,9,69,111,198,207,104,130,29,243,47,182,154,48,166,143,191,209,38,99,208,142,100,185,19,223,28,181,28,200,55,222,214,164,211,182,108,49,159,189,207,243,38,63,241,216,221,184,196,13,226,37,69,147,8,152,202,93,112,177,34,69,119,186,214,121,99,37,174,239,219,57,177,239,47,106,87,245,190,93,226,35,18,135,47,116,131,228,235,192,129,5,6,231,228,210,217,106,138,110,111,31,122,113,169,69,36,103,248,77,170,177,218,120,55,114,97,236,148,56,165,96,59,0,222,95,214,114,69,126,123,194,205,68,56,181,116,160,235,2,102,52,244,218,230,48,77,186,217,202,4,74,141,119,186,219,37,168,42,225,86,14,147,148,71,242,122,173,47,138,30,44,213,46,198,197,135,241,240,30,245,149,86,52,44,0,167,216,47,132,13,225,196,101,35,101,112,182,211,150,185,44,221,164,224,166,179,108,50,65,2,6,230,85,43,138,98,242,164,181,114,22,224,238,199,56,193,57,3,22,142,45,162,13,135,84,216,250,5,160,172,156,245,237,102,4,152,170,122,176,244,161,194,236,132,180,232,178,74,25,104,132,252,80,14,50,15,70,8,69,220,145,168,37,66,243,136,244,67,29,39,69,124,26,100,249,119,215,166,63,11,93,107,65,2,87,245,110,66,25,119,102,58,147,158,83,3,222,96,85,42,102,119,7,243,199,156,42,107,137,223,4,11,30,223,146,9,250,92,50,234,6,156,10,94,116,153,62,227,122,181,247,105,199,31,206,114,45,54,209,59,246,43,223,62,100,193,121,35,187,98,67,214,62,41,232,32,66,199,188,180,186,237,99,150,43,125,200,180,48,148,150,134,156,90,15,158,159,82,221,140,77,106,174,99,224,252,218,253,221,109,239,153,250,44,65,236,188,21,206,2,148,83,240,133,59,97,135,17,229,82,205,204,94,107,123,130,1,197,235,34,131,240,158,51,41,74,242,116,121,81,248,119,125,155,55,222,86,161,193,222,39,59,240,25,245,203,5,238,0,92,120,12,208,192,248,9,182,216,224,205,160,104,118,185,72,195,233,215,42,241,126,135,181,66,193,40,194,2,200,10,186,190,23,84,85,28,36,104,228,84,244,246,120,206,136,248,164,57,245,57,232,54,175,244,72,111,139,74,43,172,21,153,217,243,22,172,3,225,196,47,93,60,132,44,80,233,14,213,123,49,154,76,168,60,205,102,99,104,185,108,167,106,103,254,241,189,25,220,197,86,51,94,201,230,231,144,57,48,219,40,216,194,244,179,248,192,109,123,200,230,36,63,57,90,86,19,214,96,172,94,147,0,116,8,91,240,234,94,194,128,66,178,84,86,10,145,118,54,79,189,130,91,173,166,196,113,42,218,99,69,7,66,218,169,93,123,102,152,218,234,16,218,195,182,0,235,51,18,174,191,138,187,98,132,14,49,237,4,183,178,28,127,46,120,46,108,160,150,252,12,106,179,107,94,89,106,202,137,152,43,3,145,47,97,42,201,99,103,140,65,87,118,129,179,60,108,37,187,54,235,30,77,175,143,205,0,211,136,45,137,2,141,4,229,34,162,199,97,70,94,226,27,147,68,33,143,113,186,66,28,251,113,107,126,156,173,85,250,226,180,127,251,253,105,11,48,170,254,171,51,102,131,179,22,238,160,43,174,61,238,21,63,107,178,119,176,191,126,86,230,119,82,182,232,11,137,36,56,40,148,185,168,40,128,95,82,59,250,39,125,228,162,92,180,159,144,19,56,190,226,21,55,171,26,156,156,171,153,183,213,185,109,139,141,141,186,57,62,215,140,55,38,59,72,204,206,149,56,148,245,161,23,220,174,239,46,229,126,11,204,109,161,180,208,49,240,118,245,255,76,219,108,150,190,160,86,191,236,8,111,209,162,219,60,133,157,212,154,39,92,91,14,77,101,147,233,105,112,27,167,94,142,125,29,144,79,226,159,237,210,183,49,43,48,180,103,64,183,184,88,203,77,189,60,242,90,76,131,93,161,173,237,119,245,113,214,208,249,58,49,190,227,206,21,54,13,9,49,78,155,57,76,150,243,105,78,152,205,100,10,89,94,94,242,188,117,91,157,151,140,115,225,174,135,226,128,95,214,106,39,199,212,135,249,144,126,158,87,38,187,199,40,190,191,187,143,165,204,136,81,114,128,51,243,67,179,72,98,247,82,192,255,174,254,76,237,223,37,210,132,149,84,5,202,216,143,74,179,4,128,165,124,84,138,105,49,171,74,248,14,237,113,126,120,234,121,196,51,116,111,185,200,208,230,75,89,100,39,149,90,43,159,90,124,39,14,231,194,31,20,234,238,149,133,228,151,248,254,66,241,222,77,42,58,230,172,33,130,74,140,68,198,165,126,137,177,152,141,176,198,235,49,230,73,102,83,188,94,184,253,210,126,0,3,46,89,30,97,249,142,37,152,178,146,192,14,221,201,68,156,43,250,156,198,114,111,159,187,206,63,37,209,19,44,121,177,98,137,130,46,225,61,4,170,144,211,51,60,23,209,183,27,43,181,174,79,122,29,233,97,243,162,164,114,211,83,64,97,169,222,102,253,152,147,182,241,152,236,244,130,76,224,178,233,108,182,143,83,108,173,124,169,151,96,23,181,18,26,43,52,137,245,198,80,34,17,88,235,131,29,228,176,187,195,85,24,244,204,242,12,244,219,60,31,82,122,114,89,194,227,160,158,248,132,33,229,148,194,5,25,88,190,215,159,189,117,213,119,82,1,184,168,221,154,17,104,60,68,4,137,204,121,223,190,245,30,34,194,23,109,141,251,185,6,63,120,226,129,78,39,225,106,224,195,115,222,236,102,83,35,188,233,71,101,160,180,133,220,132,84,210,15,80,47,108,84,25,173,197,193,84,238,199,192,50,91,130,143,168,183,83,7,93,9,139,186,152,103,223,82,185,98,202,254,218,242,107,143,173,2,46,218,231,171,118,240,100,247,59,77,51,93,223,10,187,92,28,55,195,89,207,181,135,110,210,109,15,186,130,155,244,76,170,171,39,193,118,107,199,46,230,253,76,123,217,224,113,183,150,107,106,10,17,119,225,159,19,176,170,197,38,51,86,195,245,140,157,151,190,156,102,139,212,207,107,245,73,212,14,224,213,58,143,103,152,220,31,25,105,190,251,125,228,178,44,89,28,250,62,168,104,210,237,232,61,153,45,140,157,244,21,229,169,83,47,150,239,26,22,137,89,30,133,6,73,73,172,129,196,99,111,255,87,47,101,150,168,12,138,112,54,17,97,50,161,152,93,49,69,147,51,108,129,89,213,159,140,2,16,145,151,219,23,98,125,187,4,234,45,28,160,71,13,151,136,23,163,78,234,115,62,182,47,35,82,19,141,133,73,247,176,72,95,136,31,125,10,40,248,49,36,133,76,167,248,98,220,237,40,235,20,246,229,150,123,177,209,174,51,162,220,187,153,151,243,13,160,202,161,159,101,107,182,230,42,57,238,76,253,96,176,29,111,138,69,166,169,250,130,74,137,121,0,253,139,247,44,173,173,109,121,61,196,6,12,176,153,2,244,118,158,255,125,136,191,44,142,8,28,243,89,122,254,146,242,94,24,208,107,240,195,136,241,241,112,253,213,164,36,31,231,168,105,170,246,230,221,147,177,2,154,253,41,161,145,234,137,240,84,133,237,187,202,148,2,242,241,177,235,14,64,247,229,241,49,156,123,4,157,138,228,52,92,127,48,214,49,158,240,19,68,76,189,245,195,232,156,17,123,167,243,242,214,89,33,238,25,161,251,224,185,61,229,13,157,143,206,96,15,74,108,96,116,1,133,67,101,246,81,26,61,204,195,254,179,129,25,113,130,144,241,173,34,169,179,125,198,249,101,170,41,177,40,122,121,204,237,211,215,103,29,29,14,185,88,30,36,93,57,184,151,132,56,18,167,83,238,68,207,94,131,184,2,139,32,50,139,106,229,75,1,36,96,208,245,108,159,192,113,104,163,188,7,65,250,136,145,207,219,124,120,224,229,98,229,196,212,2,46,193,201,145,39,125,246,79,51,147,186,163,253,74,157,211,226,68,32,50,41,231,97,243,26,21,106,116,70,253,215,60,16,29,100,239,89,196,142,203,148,102,15,102,225,151,231,166,208,140,12,179,155,121,211,250,119,58,102,24,207,127,134,249,88,21,28,121,185,115,0,223,192,67,169,48,127,204,217,53,244,102,249,236,191,39,11,152,234,136,222,172,53,214,170,167,141,214,0,172,246,13,217,252,186,10,159,164,8,65,100,101,5,73,134,220,164,188,121,159,164,155,214,94,247,219,8,88,34,244,185,234,168,201,253,213,76,197,11,108,24,91,121,189,0,100,83,158,56,237,77,213,204,137,103,67,253,102,214,146,68,183,213,184,35,52,182,195,50,229,229,140,237,60,218,193,202,6,248,39,220,86,83,30,199,252,231,200,146,119,240,7,110,57,29,107,42,76,223,185,73,93,183,64,102,228,89,67,253,131,108,77,210,200,152,19,175,139,140,206,205,84,175,172,99,217,167,95,161,116,184,224,46,103,121,159,179,104,159,181,165,67,150,51,5,82,48,93,78,155,29,104,215,130,123,164,31,62,180,149,21,113,30,79,236,142,125,123,110,204,9,186,125,119,38,113,186,199,159,121,142,37,231,3,57,235,42,222,23,30,127,98,52,39,232,73,184,27,24,131,214,208,142,104,2,130,56,166,170,166,10,181,237,25,111,47,187,105,235,142,6,46,92,240,33,208,106,213,67,200,172,91,170,201,130,120,216,55,19,98,110,150,228,22,197,135,90,28,212,141,23,45,132,206,17,174,112,110,131,202,163,48,160,214,192,126,175,113,211,171,71,117,97,141,173,1,145,211,181,110,139,185,191,112,23,217,171,65,191,165,59,178,137,161,234,245,16,83,40,95,160,166,155,116,235,252,67,67,4,31,67,28,16,249,243,205,158,193,253,241,36,154,61,166,102,20,168,83,22,69,246,139,54,110,156,84,161,246,203,4,30,150,251,204,93,19,201,214,238,133,83,85,106,174,107,119,248,156,216,245,83,98,100,149,0,158,254,224,179,44,130,110,110,41,61,111,140,32,222,162,12,142,206,44,184,57,226,59,61,136,188,170,10,210,25,185,66,134,166,169,30,174,67,59,202,133,68,91,230,232,150,106,101,99,34,121,172,186,208,150,86,73,77,26,0,50,150,220,118,198,57,95,126,69,140,6,254,150,170,242,204,179,194,5,250,50,24,23,22,218,255,221,170,212,78,255,232,28,120,117,209,23,253,106,135,251,144,54,242,178,118,225,66,60,76,81,78,239,197,218,94,185,252,47,132,79,160,224,95,204,209,169,219,176,97,137,110,163,73,18,52,77,171,13,243,171,138,33,135,81,115,170,166,161,36,30,33,165,95,78,109,219,35,197,234,84,56,108,41,192,50,143,58,165,71,210,28,81,50,75,198,129,98,206,65,192,177,211,242,230,149,228,46,34,77,231,96,95,202,119,168,163,102,28,37,155,136,100,83,71,57,101,79,223,71,215,116,84,246,117,238,50,111,118,18,21,80,172,219,117,178,205,12,2,192,186,86,169,66,63,126,51,106,99,42,244,106,254,30,14,181,9,7,54,81,250,199,63,87,207,101,175,159,143,192,188,232,223,184,49,163,136,245,91,249,149,32,117,158,159,162,223,153,148,210,183,212,56,100,93,136,19,75,252,193,96,36,208,185,229,151,91,216,169,160,85,165,239,36,1,28,34,198,243,20,253,41,77,101,196,212,196,8,2,145,71,254,11,253,3,192,215,142,100,11,219,230,246,67,221,137,95,118,184,30,2,111,120,212,35,223,171,100,47,61,17,57,172,240,145,1,142,42,192,6,209,164,143,154,41,186,126,211,31,126,202,242,128,228,252,38,35,232,113,80,234,110,15,237,118,75,116,135,254,144,24,84,6,107,210,196,199,144,63,35,56,30,205,191,8,37,255,149,93,92,219,107,91,86,63,195,104,230,86,238,120,125,59,56,32,16,78,168,116,147,59,26,119,233,182,24,181,191,33,246,53,81,29,16,210,212,30,236,206,16,79,37,101,123,69,242,110,160,227,119,118,22,67,45,138,161,242,54,91,46,110,178,103,84,158,208,1,105,232,224,101,156,228,245,14,239,196,109,246,235,243,198,139,222,174,170,175,15,197,238,112,63,183,163,233,171,88,249,30,163,208,123,142,122,228,239,204,166,31,133,21,137,240,167,191,241,249,157,12,172,177,76,228,126,104,20,161,105,21,158,129,252,56,39,95,178,211,226,62,73,203,110,113,75,227,227,125,219,226,31,173,248,65,197,198,248,131,192,183,143,159,136,99,223,93,255,118,240,209,106,221,122,204,76,224,212,42,65,181,239,89,20,232,160,68,208,154,152,99,139,115,89,74,85,222,116,163,39,64,245,186,44,8,241,17,183,82,120,7,141,246,201,140,94,135,201,103,139,189,180,142,250,45,238,209,13,214,112,26,187,206,136,236,225,184,115,154,222,80,119,240,204,94,96,86,183,160,197,228,243,222,225,105,46,110,38,212,112,102,182,177,114,243,190,19,54,9,202,195,240,169,153,105,110,227,15,182,244,143,166,38,158,96,0,195,136,121,234,33,6,154,107,216,142,148,252,73,220,188,31,116,245,33,108,179,116,118,103,28,21,95,74,107,136,95,183,112,113,67,60,12,200,181,98,192,73,224,177,110,112,91,182,237,97,11,23,18,23,142,134,193,187,144,238,62,119,159,233,122,38,138,3,7,150,110,231,58,233,143,208,129,22,27,229,231,213,124,180,227,250,39,165,244,232,26,95,59,150,216,68,175,21,132,91,17,35,156,174,211,12,59,222,195,236,131,234,6,89,123,184,248,106,177,40,67,197,46,8,229,91,101,73,139,42,217,70,149,40,57,18,232,168,25,199,86,138,246,86,132,99,156,42,182,176,152,84,251,134,242,42,125,123,111,168,4,84,26,193,23,67,186,52,9,68,65,109,143,124,195,148,219,159,189,125,3,216,128,136,153,138,196,188,237,103,120,75,98,98,232,187,194,34,186,149,151,43,70,189,106,220,57,250,188,106,214,51,221,250,96,169,143,118,254,171,68,60,210,97,170,208,156,137,200,185,245,68,21,109,60,91,10,16,197,144,109,75,51,135,211,224,231,91,121,214,51,215,52,3,73,212,16,119,60,150,93,212,130,178,71,100,75,50,28,171,157,45,156,81,90,206,166,208,182,228,29,57,61,202,144,23,38,36,238,184,1,77,181,131,128,196,164,114,56,173,234,102,168,197,138,17,67,176,235,185,215,99,241,244,191,250,5,105,226,142,152,156,178,23,232,117,11,238,161,64,189,124,9,170,75,83,117,155,248,115,134,143,118,167,161,208,88,21,223,60,104,40,33,255,199,253,97,147,78,142,68,154,31,170,81,99,133,195,159,181,123,100,51,151,234,98,27,12,218,25,143,245,91,171,20,210,198,168,151,125,208,75,22,172,61,142,82,156,76,228,24,181,234,216,235,23,91,72,12,24,234,144,102,106,113,56,90,90,55,255,14,80,191,168,164,199,92,11,226,0,159,214,189,130,246,187,205,92,91,140,234,141,2,7,24,182,86,111,153,56,235,242,10,34,197,26,125,111,150,151,163,214,158,204,230,3,65,83,13,224,109,127,194,61,8,191,169,83,127,240,17,242,181,160,206,87,242,91,114,199,32,155,238,169,22,6,108,77,219,22,186,216,190,87,95,33,78,103,175,62,188,176,95,241,141,244,104,40,195,37,243,117,218,218,251,68,103,83,51,179,85,194,10,159,115,199,122,155,149,250,109,164,53,135,39,56,230,212,78,11,246,165,237,180,118,0,224,132,229,177,73,193,166,171,87,8,159,179,173,155,239,75,216,115,216,224,159,172,230,229,168,159,188,249,66,222,191,23,169,14,208,36,165,110,42,81,189,106,52,242,8,164,21,40,5,110,78,156,141,201,95,203,0,25,104,186,168,191,214,111,238,70,30,33,131,229,196,177,98,37,81,246,157,134,63,213,44,216,122,53,72,14,10,34,55,71,211,98,239,89,218,54,197,15,226,52,143,72,37,122,152,231,64,162,20,62,237,58,111,239,245,20,240,225,233,89,194,241,148,252,87,153,41,120,167,62,66,147,13,186,46,203,168,20,238,20,52,236,52,246,73,156,188,109,66,217,48,152,231,113,223,76,51,153,173,2,158,239,30,88,199,221,192,150,20,72,52,222,189,3,148,246,233,247,191,249,191,104,58,11,183,38,224,238,111,43,32,161,132,168,136,228,20,80,4,164,148,144,218,64,68,68,98,2,2,146,3,105,164,59,55,16,37,36,38,82,42,49,17,9,5,233,174,129,196,232,73,55,163,71,215,96,27,172,222,235,121,127,207,243,63,156,111,156,235,124,238,251,68,162,19,192,32,155,95,240,159,152,185,107,215,142,20,116,196,108,204,30,211,232,60,142,179,56,133,213,60,27,201,94,173,84,35,147,201,175,158,236,144,82,216,154,64,95,195,160,123,245,144,93,38,117,21,232,252,237,103,241,5,236,13,102,132,39,81,225,51,247,187,208,25,169,84,168,52,40,185,117,118,110,5,236,40,150,29,6,103,7,248,198,43,255,217,56,216,50,2,111,157,195,69,138,145,33,164,124,136,20,132,83,241,90,80,173,234,9,253,254,127,254,55,133,87,162,150,59,99,231,136,71,171,20,222,162,191,74,135,173,77,230,135,231,102,141,179,194,47,183,98,223,74,123,245,167,48,15,38,50,220,211,251,18,153,190,191,213,198,125,105,77,254,177,116,27,68,220,108,142,161,127,245,96,118,248,151,175,40,157,208,39,150,222,219,105,58,46,210,255,99,61,151,222,182,16,225,169,217,158,239,159,23,172,116,149,242,93,11,15,29,119,246,47,233,207,50,219,244,62,78,187,247,254,203,253,34,102,244,242,210,242,150,79,207,164,0,254,121,26,61,215,239,1,229,179,38,81,80,97,208,181,117,135,96,89,217,196,151,161,40,4,186,39,212,77,114,139,67,77,103,250,209,141,245,203,176,159,145,79,49,161,167,119,155,183,193,72,231,155,127,243,200,150,238,205,169,11,180,131,185,207,212,103,225,68,42,87,243,254,40,104,182,45,150,127,43,196,62,62,227,181,27,79,216,209,87,81,85,246,1,210,95,99,248,28,53,150,50,186,221,124,196,246,207,144,23,125,247,26,94,200,30,160,186,227,158,167,149,249,188,95,220,78,209,230,84,148,180,12,78,62,154,178,150,197,51,179,110,120,182,30,125,188,129,170,190,12,89,227,57,187,242,67,43,89,237,79,70,63,100,28,96,103,98,123,111,193,144,154,65,212,124,60,234,160,234,166,79,54,30,186,121,126,70,225,110,178,90,212,175,155,93,76,210,128,38,55,208,34,150,48,130,195,238,205,80,132,26,225,105,194,235,75,89,159,30,244,163,31,219,56,14,234,54,82,45,31,192,190,126,144,176,47,108,185,145,32,221,88,202,22,202,126,154,182,77,59,115,22,172,6,80,78,94,151,202,189,187,243,110,43,99,14,226,180,38,107,120,69,169,100,80,178,58,10,86,154,245,144,118,136,62,29,122,34,242,235,39,104,120,57,169,235,53,64,47,181,111,131,223,88,237,102,92,72,19,171,121,56,75,105,233,139,228,42,76,226,121,63,240,220,182,226,79,43,181,240,80,114,171,232,205,99,94,133,6,183,143,167,128,83,67,157,136,213,63,126,17,47,43,134,169,97,52,107,193,34,161,168,27,41,23,169,146,53,155,43,130,27,25,105,143,171,248,202,219,186,160,193,175,45,124,24,2,220,83,235,151,211,253,19,209,73,102,69,3,66,87,183,164,39,17,33,229,63,169,67,197,41,248,101,146,166,251,30,155,162,230,99,173,10,141,6,221,67,254,30,35,27,105,193,141,167,243,99,198,107,49,163,141,108,76,88,163,51,181,154,171,167,199,97,185,170,148,165,65,162,57,0,135,117,229,108,80,217,77,113,49,161,60,242,188,66,225,232,182,28,5,148,171,62,85,230,186,154,82,83,247,255,83,238,237,247,178,60,223,72,179,133,246,5,28,126,4,190,89,82,87,193,102,251,21,254,50,184,11,12,97,248,129,90,247,26,95,235,54,123,240,255,217,87,239,57,143,250,153,125,90,125,216,252,211,35,186,46,10,58,51,88,198,109,88,233,204,251,147,213,159,107,247,225,200,183,242,240,254,76,230,56,117,249,139,137,111,214,255,7,156,108,220,105,63,51,42,229,60,166,59,27,151,100,188,118,146,151,160,9,176,38,50,60,16,205,219,154,138,212,183,182,48,93,51,174,187,179,121,189,0,154,187,26,170,156,173,138,125,90,42,186,117,197,229,184,75,50,218,26,164,168,151,42,56,173,169,252,190,49,159,123,44,31,68,243,94,252,6,133,80,218,191,148,221,30,122,102,235,164,184,3,0,121,102,231,132,14,130,19,193,99,142,245,255,132,18,102,124,138,32,238,37,172,175,165,197,62,18,205,172,253,51,216,120,200,166,14,87,197,220,43,102,234,148,62,138,130,54,103,80,187,93,194,28,21,29,94,109,31,205,156,229,45,232,239,109,131,206,14,233,155,113,7,83,211,64,21,119,7,176,26,254,246,154,121,228,51,75,215,83,121,202,132,155,94,251,64,164,26,100,61,96,235,12,89,59,101,19,58,41,24,177,4,194,175,170,213,87,151,107,39,22,175,69,253,77,220,95,122,249,142,61,13,129,113,247,205,236,7,48,136,175,59,223,226,150,249,0,186,134,133,97,12,57,233,87,165,255,250,188,56,248,76,221,95,8,125,217,223,189,25,113,144,3,67,5,57,44,86,84,218,163,102,254,76,89,219,41,66,2,226,99,99,223,165,189,136,7,165,14,172,23,125,223,137,113,214,27,45,58,71,115,237,211,233,48,179,100,12,160,241,203,51,63,88,211,181,158,125,109,240,168,57,171,95,144,240,112,255,55,6,159,97,1,97,48,140,200,83,241,237,226,142,123,6,46,207,79,253,255,80,108,81,73,187,95,81,130,165,147,136,177,55,253,131,222,191,200,185,76,210,224,227,194,243,52,69,226,210,39,37,225,131,27,153,103,122,168,249,49,147,126,14,0,25,226,83,123,145,168,48,73,39,246,137,206,73,148,182,98,219,140,3,76,53,249,196,157,107,71,60,186,86,30,27,54,108,0,242,252,206,70,30,241,212,34,29,44,230,160,197,28,135,3,2,15,144,158,207,34,90,146,207,111,189,173,183,130,125,93,96,165,231,16,24,48,28,1,200,154,90,120,120,236,68,77,81,70,64,190,125,10,33,25,214,161,251,174,248,237,4,244,76,190,204,61,74,176,87,141,78,56,104,96,96,85,70,85,73,154,190,156,198,101,234,184,56,102,92,188,198,208,97,156,172,220,187,111,187,136,60,235,55,22,252,112,160,220,74,94,25,11,220,56,138,157,75,233,13,51,33,233,126,171,134,162,237,155,201,150,72,170,229,10,90,239,8,226,41,109,114,158,247,137,106,178,87,46,73,233,149,30,115,243,118,235,120,50,87,199,194,218,213,21,81,190,216,234,94,183,216,250,199,172,220,102,178,28,130,84,16,222,109,35,237,79,242,85,181,222,153,187,66,146,172,159,175,210,63,43,187,21,124,58,97,22,189,94,58,156,170,119,166,232,191,249,79,193,176,20,73,61,215,1,110,219,97,34,8,30,198,109,147,116,56,181,203,184,110,170,139,16,100,85,220,44,149,193,133,249,141,64,159,62,128,14,68,59,67,183,150,15,70,116,172,36,72,47,22,174,28,64,9,205,90,152,14,104,224,152,190,226,91,227,54,9,70,155,176,189,218,225,26,130,251,8,4,191,175,150,245,104,213,235,186,18,90,22,181,91,183,242,81,130,215,220,38,112,198,81,129,221,62,129,103,255,88,11,27,54,255,171,87,72,165,179,228,103,43,43,145,226,204,11,171,23,45,241,230,188,26,53,123,251,59,215,147,90,67,142,254,15,255,151,236,126,37,180,100,31,27,172,183,168,125,36,91,126,5,130,208,232,126,42,206,126,102,33,106,240,222,169,154,243,146,82,229,94,24,58,22,60,66,18,137,68,210,93,214,6,246,37,92,212,105,185,118,249,9,112,110,32,194,32,149,115,236,36,68,68,75,203,117,37,99,118,169,159,158,119,45,69,194,76,40,47,227,212,153,43,209,66,169,135,19,247,145,150,73,57,98,13,35,12,153,221,178,106,160,135,19,211,3,16,5,177,2,199,184,213,189,138,214,186,32,67,113,128,162,93,75,206,105,150,240,46,135,217,162,103,210,107,235,42,18,7,123,85,179,39,82,144,241,251,148,170,84,53,254,223,66,61,9,162,102,234,222,62,121,1,219,152,236,173,247,250,108,12,98,171,120,16,126,101,78,42,76,192,86,209,10,106,119,167,179,99,118,34,56,64,128,166,90,29,215,175,42,90,154,126,44,26,35,50,42,72,91,90,221,86,147,68,117,11,59,37,196,143,213,182,35,95,167,71,217,78,29,248,230,102,253,62,135,248,158,113,237,118,59,3,156,139,205,216,32,205,245,104,60,241,89,74,243,39,176,232,7,101,179,108,162,246,235,120,78,213,150,66,191,87,189,33,213,126,48,207,39,117,235,120,238,95,221,25,123,73,174,60,219,91,47,73,4,15,197,27,152,184,31,219,177,84,156,52,45,33,244,247,166,179,149,193,131,208,179,173,156,19,237,92,33,173,135,15,118,208,61,9,105,242,247,46,78,133,146,224,199,218,139,85,165,206,227,138,1,147,111,235,128,129,211,178,162,51,125,218,2,215,28,35,103,57,59,65,245,99,176,136,6,154,143,150,126,103,87,197,73,202,208,229,146,178,75,141,46,52,93,169,132,243,224,123,219,209,125,173,71,253,9,117,232,32,5,127,249,193,8,159,246,135,55,176,45,84,222,36,76,230,155,172,150,20,143,209,43,44,23,137,16,10,119,77,31,40,95,95,193,47,46,246,169,249,126,41,178,30,75,185,129,14,51,61,92,63,148,222,77,92,133,58,57,175,148,183,181,101,233,187,119,117,121,24,181,173,184,189,109,42,179,229,189,172,122,127,11,59,28,32,243,78,145,97,131,107,196,103,62,5,143,174,105,65,70,157,164,157,128,254,76,192,28,226,29,126,233,148,9,51,16,191,149,203,230,175,134,153,164,1,82,219,172,39,44,230,43,87,123,102,55,71,242,19,150,82,130,107,11,173,228,47,66,155,223,14,126,169,52,201,221,211,167,166,132,125,165,40,98,194,141,185,144,147,224,134,166,127,164,24,255,173,117,104,195,36,110,225,46,46,86,234,51,165,238,188,111,203,152,20,126,65,228,124,186,225,241,108,115,221,12,50,131,244,206,48,95,197,12,34,163,86,60,218,254,168,240,68,229,105,206,58,53,22,100,95,222,118,254,155,182,224,63,166,31,184,18,47,58,179,16,68,67,101,64,160,103,91,41,173,129,1,68,235,23,167,250,110,205,62,34,50,20,22,34,87,22,10,51,6,105,149,251,24,201,172,199,24,245,37,225,107,98,220,199,255,41,1,228,117,34,163,25,135,191,249,41,243,230,7,27,60,56,178,124,34,155,139,2,178,237,71,208,197,92,175,102,62,20,221,230,233,212,126,126,163,29,178,140,254,146,166,105,113,24,136,242,31,187,163,166,228,186,67,171,18,5,137,116,202,125,166,134,154,245,51,167,168,87,126,208,179,60,87,75,122,185,121,174,26,130,54,200,111,61,153,31,11,92,128,208,190,248,45,159,103,90,251,200,207,189,105,182,166,104,10,73,112,188,158,82,160,78,226,13,147,127,126,195,116,53,82,54,74,194,125,243,181,225,185,248,146,49,170,45,78,178,226,185,88,210,99,119,219,194,239,41,90,204,76,244,156,45,253,235,24,82,187,176,123,188,163,120,116,247,111,22,73,116,241,76,228,169,98,217,232,193,58,199,131,92,136,248,151,180,99,209,240,14,121,231,63,151,168,73,107,28,216,51,45,155,199,95,87,205,125,103,30,59,67,145,87,236,7,30,84,227,251,197,184,250,80,26,249,127,234,117,160,223,0,103,14,161,230,15,39,96,62,236,52,211,29,68,249,83,251,150,254,30,220,106,139,239,153,176,140,199,29,190,3,91,250,92,229,157,197,252,102,202,113,205,21,143,197,75,220,6,142,182,111,150,27,62,74,52,139,83,245,103,33,97,123,200,207,140,253,189,34,230,71,211,168,128,101,193,137,61,144,118,111,88,92,230,0,114,29,223,60,103,128,153,43,255,139,240,253,69,150,99,60,179,75,182,220,172,124,17,209,160,30,64,178,151,154,156,185,117,218,17,93,37,49,65,3,186,164,82,102,238,165,234,25,210,210,192,231,76,165,245,62,181,80,176,132,111,215,113,232,34,18,9,8,207,218,33,20,17,117,207,41,21,63,49,169,43,247,118,80,214,129,146,39,160,63,147,176,126,55,147,57,177,203,121,209,191,52,218,203,175,220,75,155,133,88,25,27,11,175,127,149,78,106,184,252,168,68,71,2,18,198,248,83,71,87,127,84,232,165,80,36,53,59,40,188,160,12,121,163,184,211,85,243,251,49,201,210,108,10,239,207,69,26,63,246,122,29,161,114,60,118,15,153,115,103,194,31,49,246,194,116,128,114,64,58,64,58,207,121,212,255,137,56,234,230,254,243,28,28,230,181,24,19,147,64,242,162,4,58,9,202,183,96,47,252,245,106,73,232,47,89,30,20,127,43,116,155,78,228,31,94,186,244,214,127,65,121,117,81,225,171,154,157,13,60,167,23,85,159,113,201,202,38,62,210,91,35,181,143,68,203,182,131,75,108,195,139,15,20,171,30,184,179,146,120,68,201,74,153,168,134,196,174,233,199,27,98,138,170,69,181,23,147,45,203,6,151,214,222,186,112,128,224,88,64,46,199,47,126,11,116,120,109,62,6,9,126,231,82,214,121,189,59,193,169,33,182,234,17,156,198,179,130,122,113,5,204,211,196,161,182,205,240,30,199,167,190,204,174,186,242,56,124,245,167,165,172,44,58,46,51,59,224,161,205,76,247,20,68,126,214,87,226,143,157,25,101,7,89,39,97,106,58,56,251,86,129,88,240,197,80,68,145,253,240,20,130,153,59,120,105,25,216,109,162,166,154,9,27,110,243,155,185,59,133,241,152,219,175,138,13,232,44,105,59,254,205,239,150,235,69,253,112,52,219,148,224,158,169,6,235,26,19,167,156,6,44,124,254,134,63,195,126,190,177,142,186,156,84,138,148,164,46,156,89,115,155,241,55,159,239,255,219,202,40,218,62,135,56,140,220,221,11,226,182,49,62,191,103,148,6,171,3,250,77,183,197,82,231,217,41,221,44,185,234,147,232,120,22,218,254,101,226,75,152,226,154,168,74,6,178,77,165,211,143,45,85,198,179,230,187,202,44,224,46,103,17,223,77,231,230,111,47,206,252,212,156,169,122,245,243,84,211,215,142,242,227,99,249,175,47,250,221,182,33,117,132,190,27,72,231,119,158,12,162,158,237,53,23,23,57,102,64,106,153,143,221,220,139,40,102,224,220,219,7,139,237,63,134,45,220,104,11,211,25,91,47,206,119,150,181,173,215,241,176,181,120,231,185,198,76,26,61,227,55,174,146,126,196,214,161,47,111,197,254,189,58,236,69,144,150,85,215,51,202,137,101,226,169,79,173,228,188,23,139,219,161,248,106,27,122,55,226,7,48,89,249,215,143,155,71,17,66,197,254,148,161,148,185,181,225,176,208,172,19,61,89,129,222,97,21,204,187,192,121,30,238,89,79,219,47,2,89,12,214,214,138,204,105,101,52,97,176,237,162,87,37,85,183,252,234,242,248,69,78,207,240,216,124,249,41,76,23,94,121,233,240,247,14,66,162,174,223,104,237,239,14,104,27,225,250,170,30,137,47,163,101,16,131,126,82,176,170,161,71,179,19,128,112,213,213,89,255,108,245,152,249,168,91,235,59,200,209,119,202,87,43,7,226,69,138,183,154,220,75,136,143,58,215,108,247,97,179,226,69,127,157,84,47,82,77,43,1,40,248,106,34,90,143,187,87,67,97,127,99,39,63,165,196,119,206,123,247,74,63,1,113,22,132,76,186,111,45,117,255,75,33,9,254,234,220,62,89,105,210,0,68,241,95,149,56,159,180,9,243,32,154,18,144,7,109,42,211,251,141,216,92,158,30,241,41,216,58,85,101,221,43,102,253,249,199,57,225,118,18,223,194,106,141,182,206,178,208,75,75,134,147,254,134,217,223,28,235,207,254,139,166,176,216,242,202,235,95,243,139,236,236,124,140,181,165,179,203,118,63,246,102,63,76,184,115,213,65,72,213,211,73,137,139,79,177,14,40,11,127,158,29,55,116,189,244,78,223,90,113,130,202,45,250,6,2,67,53,127,167,38,77,65,5,54,85,55,179,21,150,151,201,89,5,117,186,4,243,151,220,194,188,153,179,118,247,35,27,114,172,171,238,12,138,178,151,145,167,104,243,136,139,204,101,155,218,182,107,99,238,149,212,129,217,232,104,160,198,236,97,95,40,110,17,231,166,96,137,0,6,118,149,195,156,99,105,231,254,164,221,85,14,247,222,57,175,21,46,237,252,210,131,121,92,71,69,245,109,211,194,7,116,194,207,190,56,133,191,100,161,40,73,87,175,44,172,162,114,3,163,4,66,254,154,83,183,27,193,160,51,102,198,248,116,143,40,173,67,107,54,238,223,213,177,16,158,73,61,216,218,85,186,35,228,196,49,198,251,192,207,48,195,232,140,71,108,199,43,137,246,97,106,193,124,83,122,27,177,126,143,239,111,31,121,185,118,146,49,107,90,62,136,140,94,12,35,120,144,14,91,235,61,58,180,110,214,23,100,88,114,250,129,228,128,203,167,238,229,236,126,237,230,69,224,167,215,68,255,74,53,41,156,212,244,32,6,165,105,168,232,189,12,154,219,173,176,31,173,33,27,66,136,193,123,84,217,185,53,160,165,215,248,152,79,209,140,250,248,68,17,128,173,182,227,160,197,213,254,89,132,125,4,54,7,189,241,213,235,162,229,133,211,87,28,157,86,53,198,63,87,121,146,241,83,166,36,228,81,155,243,247,248,117,31,143,178,116,103,31,155,17,196,28,141,145,88,104,56,46,38,252,33,119,90,139,191,202,81,172,24,193,136,144,240,10,155,126,6,63,235,89,132,97,5,72,222,155,182,183,106,206,167,91,112,210,182,56,97,100,196,198,151,49,156,238,209,60,117,106,214,246,81,57,252,206,65,155,35,128,157,39,177,174,230,214,182,253,165,91,152,191,155,55,78,53,66,158,245,159,75,76,97,74,137,109,3,149,72,21,76,178,234,150,94,77,223,84,206,196,67,137,178,55,87,30,212,184,140,171,8,1,137,219,206,41,26,152,80,207,214,150,231,255,196,188,209,233,79,205,230,169,113,73,130,242,253,139,218,54,192,115,219,56,36,59,60,4,251,187,9,72,110,144,61,121,20,216,70,149,110,218,151,146,6,75,129,30,153,215,128,232,162,228,170,173,60,97,39,5,3,235,206,146,13,217,216,159,74,48,3,189,24,134,238,79,130,6,85,208,141,182,65,164,53,165,198,172,146,129,61,181,241,211,91,120,36,223,157,59,105,16,217,217,220,240,187,170,83,37,245,201,31,235,147,95,48,92,227,251,225,134,58,11,120,250,181,125,54,217,63,137,17,181,190,29,241,60,105,227,229,12,221,197,186,90,34,101,172,86,69,141,247,169,2,190,167,96,72,146,102,17,68,206,248,65,27,46,28,190,189,16,85,35,152,119,37,198,161,112,248,94,251,44,24,122,156,250,219,107,73,32,226,100,36,112,210,220,153,43,66,188,59,55,252,88,135,180,72,144,9,252,122,81,170,42,94,66,58,0,31,2,162,175,18,74,23,184,215,30,102,116,154,42,208,115,87,131,179,248,34,221,67,230,9,245,187,247,175,252,55,60,9,87,167,191,137,60,23,103,23,217,162,191,140,84,234,22,17,7,63,46,69,133,176,10,134,244,47,27,234,85,188,153,62,64,205,163,24,196,134,207,212,239,115,47,223,246,157,95,49,138,193,18,59,111,127,136,126,144,27,54,42,8,247,122,171,25,122,210,5,8,216,232,11,22,52,174,202,56,69,215,219,130,178,56,174,159,54,146,219,146,27,232,215,15,102,252,76,45,61,215,39,220,103,210,77,165,127,4,22,30,227,78,67,116,165,154,85,169,13,66,12,92,220,213,187,242,150,52,156,100,13,243,182,235,242,15,202,165,183,53,250,14,173,55,231,0,102,8,201,230,81,113,42,214,140,135,19,165,181,70,10,167,56,32,61,23,12,1,3,165,182,186,127,175,202,53,78,65,208,130,46,169,18,149,250,27,233,30,169,65,148,145,205,70,214,209,37,68,125,146,127,45,250,198,20,72,247,105,190,137,212,117,206,190,90,157,200,84,184,75,155,247,136,133,223,1,198,73,132,161,42,73,187,197,173,143,180,223,140,6,146,18,25,95,80,109,198,205,105,84,138,71,78,192,100,37,28,68,157,22,12,63,212,8,35,46,199,122,220,72,252,44,81,222,82,181,215,176,154,92,183,91,53,96,42,250,105,248,177,57,254,239,21,233,233,85,56,200,243,160,149,144,219,74,163,146,136,27,38,173,146,173,39,163,212,202,195,156,192,217,190,166,78,91,171,64,64,196,73,138,218,113,175,48,209,198,170,84,174,128,42,16,56,221,225,244,213,241,102,216,201,136,246,222,176,138,221,97,140,165,125,146,124,255,136,123,212,165,155,21,67,10,115,165,253,112,81,68,248,113,188,218,97,59,189,77,50,127,195,128,84,243,107,116,174,26,206,53,129,164,58,98,118,104,151,149,8,24,188,185,190,181,133,89,58,138,120,235,32,97,248,21,56,128,155,247,67,159,1,52,137,23,79,39,76,45,135,234,102,221,74,76,3,142,2,116,214,104,61,124,94,211,159,238,104,238,142,129,65,167,44,175,30,58,182,172,103,88,150,253,248,249,33,31,13,162,205,11,134,110,222,9,59,223,42,218,19,184,213,101,30,91,58,247,167,126,145,119,180,113,42,161,68,250,145,203,55,189,97,82,53,26,248,22,13,162,169,246,47,188,94,203,217,170,233,218,90,12,59,144,223,30,150,170,23,155,68,255,169,95,220,198,176,44,139,28,156,239,148,35,180,106,188,18,46,252,22,103,109,247,96,17,115,119,187,126,136,189,17,108,124,61,243,69,73,31,233,178,227,1,227,116,180,28,183,19,162,235,109,230,212,229,114,132,99,134,121,15,35,235,45,219,93,90,112,68,53,194,17,208,220,47,94,82,51,131,218,160,46,157,78,65,8,212,72,74,32,18,154,240,3,108,211,83,55,239,59,112,147,228,180,93,0,109,42,69,68,188,81,44,157,167,29,192,104,111,131,22,2,50,79,255,170,49,146,78,143,107,91,254,61,185,50,115,47,203,125,229,168,63,139,220,252,105,108,21,58,101,29,84,43,168,22,154,214,61,171,154,124,4,246,51,192,208,168,132,206,219,55,150,40,10,193,6,64,226,232,71,210,118,73,121,11,235,90,199,1,71,4,229,116,106,56,35,98,39,116,231,143,115,130,100,221,107,9,89,137,197,93,62,64,216,174,108,216,198,87,103,247,73,115,103,201,115,109,231,244,157,113,2,103,44,163,56,190,192,255,43,55,169,163,17,155,171,194,240,98,174,144,114,155,71,145,34,41,17,191,227,45,126,245,62,28,89,244,196,247,197,19,134,167,182,202,87,139,5,121,244,152,62,24,221,249,239,191,120,236,179,186,26,208,229,43,98,209,96,131,79,241,234,217,137,0,227,205,121,146,4,243,227,192,7,108,225,95,68,1,247,125,14,163,64,6,99,222,135,155,99,242,159,60,212,111,79,245,17,137,55,80,73,109,34,204,23,129,33,221,93,95,164,234,153,113,125,165,165,2,208,56,17,10,187,54,185,53,167,98,225,123,95,49,133,243,137,237,18,215,141,204,235,210,66,70,163,167,138,67,36,128,186,40,204,43,81,53,227,45,60,18,252,36,47,162,105,85,126,158,51,16,218,216,44,195,27,152,204,175,195,31,52,239,131,239,186,14,238,98,169,3,145,151,57,60,166,43,236,122,116,58,125,86,81,38,159,181,107,174,131,31,119,72,157,225,16,30,229,173,120,241,181,16,111,26,133,48,7,141,35,0,89,53,90,2,45,250,175,137,170,208,142,51,145,211,77,59,101,150,93,5,23,127,109,141,97,162,25,217,170,114,130,22,103,22,161,36,15,240,219,73,115,167,218,25,167,172,33,32,109,5,215,0,228,12,91,12,193,6,68,115,137,202,15,36,111,1,104,89,171,87,40,184,33,69,4,216,52,195,209,66,121,248,122,88,186,76,205,115,234,191,186,229,227,18,201,43,142,250,13,27,197,154,177,236,181,20,252,28,250,177,210,38,187,239,81,24,127,145,156,187,117,224,140,227,36,18,70,227,239,38,100,243,183,30,21,242,29,89,76,90,121,181,47,159,198,217,202,108,48,236,182,11,51,206,138,21,101,143,254,232,72,136,185,93,85,192,121,175,153,207,179,225,162,207,206,238,119,122,142,154,248,235,162,63,75,81,19,216,242,204,193,119,174,180,14,38,64,240,162,171,220,207,225,42,232,71,247,182,45,39,252,212,205,227,97,133,238,248,177,93,60,6,6,243,178,215,230,247,97,104,187,20,167,194,73,150,108,88,122,247,144,217,81,125,111,183,111,225,128,70,38,52,9,216,93,2,71,208,121,4,93,250,85,254,92,0,32,94,226,138,57,42,129,80,250,217,214,115,101,173,96,160,167,176,138,57,207,230,16,140,156,39,255,249,244,103,149,139,17,187,8,203,77,251,25,192,124,248,152,190,66,74,143,223,239,119,18,101,218,252,132,200,17,82,111,20,253,222,90,42,184,108,155,195,165,215,113,254,175,6,237,59,55,68,142,119,179,218,46,58,230,19,240,245,47,52,20,164,130,175,148,123,45,47,191,82,13,167,12,177,32,125,100,183,17,245,209,17,238,6,83,48,88,139,151,7,123,58,35,214,59,189,34,131,149,150,214,72,61,223,217,195,106,11,186,2,132,224,251,47,165,34,57,20,166,143,242,222,65,168,199,153,212,169,81,250,139,114,237,2,129,211,118,129,103,235,153,218,228,154,214,181,207,186,100,194,250,39,77,246,95,196,71,42,241,74,108,193,218,2,17,105,177,142,84,108,78,80,174,0,148,184,204,21,194,159,196,243,168,7,134,106,59,219,200,250,75,155,247,67,167,107,20,127,151,245,96,239,95,61,112,205,215,248,245,159,14,207,131,46,28,111,110,240,63,129,145,16,93,72,77,79,60,128,223,254,251,74,201,61,153,80,219,231,172,66,155,112,191,92,239,219,154,48,178,196,189,103,74,23,124,144,211,164,223,185,114,66,121,53,124,217,50,68,22,97,112,215,177,134,203,71,238,202,159,16,242,204,240,56,213,159,146,39,93,220,77,141,205,160,63,160,253,224,72,132,234,206,5,178,28,6,93,218,156,94,80,84,116,146,139,183,38,183,137,140,3,121,166,158,198,108,137,72,243,94,35,118,213,131,95,85,133,86,221,79,70,118,136,240,38,177,132,104,25,178,255,176,67,37,105,232,197,126,245,69,65,228,26,126,210,238,42,158,236,58,8,63,75,140,91,106,209,191,92,37,8,5,255,77,210,96,5,159,195,14,163,1,175,250,175,28,216,117,2,9,92,138,74,241,45,52,18,134,102,83,128,136,41,73,6,54,230,158,98,107,30,231,41,6,238,190,70,76,175,250,156,193,169,114,227,55,180,28,127,222,108,240,125,24,104,82,74,247,67,54,110,75,229,50,109,97,216,98,80,48,124,83,195,210,111,72,62,75,150,66,64,210,246,148,63,134,107,240,156,158,41,109,195,200,13,71,129,27,95,157,121,69,121,178,154,248,188,90,56,37,24,235,170,192,174,172,110,121,84,165,229,65,209,237,133,187,151,244,69,43,191,18,38,204,32,11,251,69,178,113,101,241,208,92,80,100,58,219,219,63,181,166,213,45,218,89,165,227,52,75,175,86,71,148,160,31,235,85,187,135,42,233,200,133,64,62,139,90,182,19,151,41,45,221,171,169,91,90,23,60,90,58,199,199,78,1,245,39,67,246,35,162,16,154,85,165,102,244,39,66,165,142,28,234,123,222,138,250,73,165,213,140,113,224,46,135,11,171,111,163,17,13,225,216,211,89,225,223,195,227,60,173,132,205,78,109,253,141,119,164,236,218,87,203,222,231,246,198,68,16,254,124,46,242,137,147,112,254,214,100,233,213,120,105,74,198,72,151,210,177,24,118,176,112,4,204,248,234,50,74,147,141,40,203,254,121,103,135,27,73,212,74,111,82,35,76,87,119,155,188,32,237,86,195,247,42,81,130,92,246,87,237,211,137,56,255,221,105,159,192,209,120,209,217,166,215,98,227,227,155,61,126,101,80,95,251,79,244,127,202,156,51,40,227,198,224,211,135,133,182,32,167,38,185,125,180,178,174,52,136,137,46,168,126,33,208,82,249,247,238,126,27,201,51,92,130,171,231,251,56,13,255,254,34,114,43,250,6,151,171,128,190,26,93,227,147,132,111,89,161,58,18,119,57,175,70,185,62,81,103,204,115,125,103,18,255,127,168,207,224,125,58,87,171,149,213,82,114,104,93,203,19,209,191,143,19,151,140,171,228,46,140,184,116,102,251,202,191,59,120,19,29,102,110,160,56,146,0,142,233,185,192,138,125,140,15,137,250,11,151,93,5,60,77,125,61,207,220,28,194,226,123,35,29,90,165,151,152,243,155,88,242,95,171,202,61,221,105,208,242,104,218,206,237,168,47,13,162,53,222,250,162,199,213,176,74,112,185,189,125,34,121,238,213,251,229,219,224,193,106,201,127,62,63,188,119,27,42,21,166,172,252,254,243,210,183,214,63,16,103,22,202,127,6,175,75,144,106,234,117,196,221,195,70,73,4,78,118,190,109,111,232,119,89,106,23,118,63,227,50,61,196,8,246,27,210,80,0,216,27,36,101,207,203,175,102,186,232,135,3,37,251,185,68,61,83,217,125,37,226,82,180,230,205,115,205,150,17,207,229,46,135,62,54,65,213,199,54,174,166,68,249,243,53,107,159,217,158,139,56,196,105,243,173,147,195,90,131,112,223,220,114,227,237,137,146,160,221,163,8,153,220,49,196,179,138,221,119,86,192,4,53,72,52,42,126,97,121,107,194,117,48,8,1,172,38,165,174,205,121,212,11,216,20,101,154,42,222,177,37,30,46,83,69,194,2,46,251,212,93,48,29,221,173,232,76,166,46,159,46,4,98,216,48,234,59,73,145,12,108,218,86,119,94,229,170,22,46,187,221,54,189,236,125,233,106,1,113,14,60,117,29,60,40,221,122,242,176,64,148,106,92,38,161,211,200,175,184,230,243,79,131,233,236,45,70,168,97,216,9,17,17,72,154,65,67,157,230,220,155,37,143,109,196,100,33,246,1,187,149,168,155,62,18,76,14,188,231,148,218,104,23,69,49,9,46,78,129,128,79,23,66,138,194,144,236,61,159,166,215,174,247,70,8,25,247,238,33,135,198,95,176,53,127,24,232,43,23,61,119,150,197,155,200,189,174,128,91,87,209,62,231,250,55,210,120,212,156,106,172,195,143,186,135,76,126,240,60,133,29,10,168,92,43,177,119,121,181,178,221,215,63,225,178,136,204,96,195,55,122,73,237,16,128,10,168,39,23,28,63,2,51,44,140,223,233,147,166,131,48,17,83,185,31,142,238,25,231,221,103,19,17,8,104,36,223,129,96,203,253,243,59,114,203,209,42,203,239,175,183,2,28,166,179,253,134,182,214,151,250,251,10,247,183,75,202,235,222,150,53,22,246,103,205,172,191,125,154,105,229,171,19,30,246,8,44,249,140,134,163,59,14,19,98,213,116,68,153,168,163,85,113,238,193,5,151,133,105,90,55,59,74,62,85,174,136,101,34,232,56,249,213,123,227,37,138,2,23,2,50,125,125,241,204,166,108,149,128,7,42,85,246,243,243,52,79,90,206,193,211,89,199,59,2,224,0,186,198,164,244,242,248,95,101,79,89,254,115,241,153,208,53,78,229,254,142,23,151,253,159,58,206,144,33,88,184,31,4,136,59,179,189,130,205,38,58,196,140,238,138,162,223,76,112,48,168,70,134,177,234,60,126,183,36,32,73,125,108,135,6,209,242,222,39,114,24,29,69,74,22,85,46,24,10,162,198,87,129,98,57,45,215,218,189,18,133,197,182,184,105,46,78,110,176,22,102,10,162,12,185,9,250,97,247,61,255,203,29,10,216,223,113,17,91,160,185,55,123,111,9,73,191,56,21,107,21,114,92,213,253,101,139,101,221,40,77,92,150,150,227,139,56,105,126,183,218,74,152,157,131,200,63,91,253,55,164,136,217,205,219,194,118,195,33,161,91,119,49,88,54,209,187,132,121,63,240,234,206,34,149,128,164,157,73,252,35,254,60,151,40,111,121,19,214,142,144,218,193,6,73,88,4,114,81,222,150,182,197,88,135,110,21,224,139,64,148,62,246,199,75,23,104,109,221,55,179,188,114,157,177,170,149,115,94,200,86,113,30,104,214,61,137,60,41,131,135,199,124,106,2,62,71,77,53,31,169,228,235,150,34,113,79,251,215,209,161,190,179,45,159,191,77,210,227,134,77,20,148,38,66,199,233,205,32,71,167,79,130,230,125,152,218,118,124,96,201,251,97,6,208,12,54,21,50,240,234,216,82,125,180,39,146,162,160,66,218,173,62,234,47,206,90,216,52,153,68,155,93,59,98,33,237,54,188,217,204,231,0,13,22,149,193,8,11,65,4,22,93,104,66,92,73,192,100,123,63,226,242,224,147,154,199,75,14,114,200,95,41,3,232,42,217,3,44,2,214,6,155,138,199,168,138,53,15,72,53,183,204,136,231,241,231,14,96,4,122,254,230,39,43,247,67,78,187,204,148,142,184,222,249,10,136,44,17,66,93,162,120,156,152,242,117,220,143,153,95,157,63,69,110,167,60,159,91,74,248,247,96,241,221,172,239,85,56,97,49,76,250,192,190,145,247,179,4,95,137,255,109,13,124,129,99,189,42,41,58,193,15,230,221,76,161,18,144,132,182,25,228,78,186,10,131,200,224,193,102,26,41,122,94,90,126,2,217,195,91,194,29,241,128,109,138,220,54,180,177,107,191,101,20,229,217,252,231,3,48,99,89,76,22,95,89,82,214,239,197,103,240,45,97,83,54,240,171,204,197,242,50,127,179,151,53,242,76,165,230,183,18,250,197,112,89,26,114,47,156,41,172,171,245,97,251,237,245,27,68,15,225,170,53,175,177,203,193,87,239,168,20,134,78,154,59,207,100,121,181,109,217,232,173,174,165,26,252,245,209,2,32,141,253,209,106,65,124,144,148,62,32,241,29,78,250,249,136,177,134,79,79,254,96,213,118,128,239,33,66,166,178,131,116,114,163,239,117,33,153,148,86,123,120,135,165,209,21,220,190,195,226,38,62,117,88,51,37,198,246,159,70,236,217,119,82,154,150,153,251,127,43,178,88,146,174,237,93,172,249,15,13,38,240,104,76,7,99,253,47,126,30,91,44,206,15,202,111,151,27,118,190,10,88,93,1,89,61,60,254,39,179,6,228,87,237,224,75,137,136,76,25,125,115,53,226,214,70,52,215,174,210,200,30,123,213,248,93,138,131,206,213,53,44,243,88,37,145,59,250,158,151,182,27,172,137,74,190,214,241,225,97,206,57,0,10,248,144,115,131,182,166,108,112,91,241,149,63,249,87,161,69,82,150,104,229,104,57,93,83,187,219,164,146,170,104,187,95,217,74,31,198,122,201,120,147,207,163,38,15,214,162,98,161,157,207,39,86,165,74,8,111,106,217,102,241,35,250,188,73,186,238,31,126,57,87,106,7,70,250,83,79,105,169,29,58,30,144,62,104,10,37,189,248,242,113,188,131,88,216,73,225,80,101,230,248,249,254,24,25,93,52,209,248,66,148,47,130,122,4,135,221,120,81,252,214,232,222,82,195,183,162,221,149,160,84,32,117,96,57,81,152,230,192,125,46,144,79,59,28,189,82,219,190,250,217,30,42,190,245,197,35,193,68,99,157,227,163,87,203,81,15,181,38,132,234,201,180,138,147,247,196,161,65,200,34,35,42,35,135,26,241,155,50,111,172,203,191,175,205,7,170,248,110,111,213,148,220,19,238,242,233,104,254,36,125,165,242,240,199,14,29,151,184,143,69,183,207,244,217,154,186,185,33,243,101,173,251,202,150,174,5,233,165,174,141,214,23,248,156,183,68,13,169,123,117,115,117,226,7,124,30,53,41,48,21,135,91,64,55,132,210,63,98,253,86,97,214,134,72,5,150,194,212,248,126,10,113,180,151,98,37,170,143,228,51,249,248,179,51,131,249,194,27,219,113,191,26,201,229,175,129,208,17,234,156,46,114,83,211,216,210,75,7,200,20,66,75,240,252,57,143,58,230,202,105,41,172,170,204,166,244,132,145,5,45,251,212,12,207,239,113,183,206,0,188,187,217,147,240,126,232,5,69,211,98,145,187,187,194,109,167,127,188,66,118,179,235,171,168,235,25,144,178,110,96,70,12,123,219,176,20,193,242,160,5,87,215,26,119,192,230,152,143,254,83,95,104,150,95,128,65,232,152,11,164,37,252,61,198,78,102,83,190,237,187,62,192,6,109,17,95,94,0,60,95,250,205,175,204,139,108,35,31,235,242,95,252,20,212,157,52,236,99,89,106,49,152,220,115,155,119,84,177,155,48,228,75,211,164,103,3,188,90,250,13,134,74,123,189,182,168,253,186,234,125,105,196,212,210,35,29,188,87,4,162,252,130,225,182,102,223,150,179,201,139,161,190,222,37,237,115,153,89,177,112,168,182,88,173,69,75,188,35,138,171,40,151,197,145,87,18,150,47,105,151,217,136,99,43,95,254,140,254,101,16,169,63,102,237,35,51,97,114,95,131,243,106,212,47,61,117,198,188,95,172,175,254,27,146,27,180,165,187,21,114,22,249,113,230,112,230,42,107,212,99,222,206,36,241,216,76,224,173,23,171,95,229,102,35,1,157,31,43,181,248,101,63,163,250,162,100,211,250,223,105,89,184,122,247,176,220,5,84,44,169,114,108,250,254,30,5,60,191,226,180,114,160,15,222,147,46,147,180,134,53,22,181,231,202,76,203,20,106,210,52,163,149,68,9,124,127,66,159,228,42,125,122,155,112,65,188,111,135,165,252,70,206,23,118,11,78,172,195,173,251,206,62,176,231,121,47,106,116,78,2,38,205,81,136,97,169,1,111,121,109,61,211,24,239,177,169,213,151,25,169,169,100,5,54,209,99,23,254,165,212,237,188,76,164,37,23,5,1,197,139,217,56,43,140,16,67,149,154,136,38,37,14,239,48,245,46,110,172,63,230,165,154,119,233,236,251,194,93,185,216,214,142,16,96,187,177,219,79,87,199,242,225,192,237,161,12,170,156,147,79,183,145,182,117,238,230,192,113,11,227,70,174,179,39,154,9,201,213,197,245,148,28,33,9,181,191,67,100,105,67,63,130,146,131,215,242,173,154,178,223,41,69,71,10,222,93,235,218,158,180,244,218,115,93,59,105,59,63,47,249,125,140,19,195,187,191,178,107,245,153,24,195,80,241,138,8,230,117,6,159,4,70,254,77,90,69,141,208,125,16,203,65,228,75,118,223,222,158,239,217,42,188,11,25,22,110,98,97,184,63,138,62,95,21,17,223,79,15,174,84,190,246,118,48,28,14,115,58,157,232,77,209,185,221,143,158,208,86,58,16,107,175,110,127,97,238,62,2,85,80,74,69,165,36,215,105,68,238,61,167,172,157,184,176,45,246,232,238,33,187,119,202,210,82,132,84,3,46,53,122,73,60,93,209,158,0,135,208,144,139,77,59,242,59,246,174,254,125,140,119,62,54,119,212,63,191,80,242,242,31,224,223,166,183,64,98,163,85,8,145,74,58,40,162,222,22,43,112,87,126,64,96,90,116,190,195,172,211,148,15,133,150,20,21,0,51,98,196,120,165,167,235,67,44,226,58,128,113,33,246,0,82,175,48,7,247,175,147,221,145,235,37,217,120,3,236,222,129,47,114,121,21,33,50,220,214,230,133,105,163,186,245,147,14,255,60,44,219,191,163,139,250,80,165,122,114,168,25,184,153,23,59,171,175,184,176,38,155,11,61,223,186,113,189,160,3,134,207,159,233,181,26,190,136,228,144,195,132,227,190,241,149,26,94,197,123,147,245,127,216,131,76,30,111,22,163,144,0,202,166,246,7,51,224,52,148,180,103,247,24,169,112,252,89,53,33,180,231,172,131,9,176,86,78,27,164,128,32,157,168,169,128,227,128,31,118,47,225,170,215,68,144,2,227,173,205,133,170,143,230,92,155,152,240,111,200,106,250,92,98,62,255,41,72,45,245,214,213,113,161,95,254,255,21,100,191,83,87,77,55,229,253,121,199,140,26,250,59,60,255,35,203,173,197,138,81,19,70,237,195,246,251,197,35,244,46,117,223,59,101,238,161,116,128,51,223,13,209,126,12,231,73,94,117,248,247,220,228,47,226,6,243,152,235,159,161,21,183,217,177,119,169,110,48,159,168,173,115,250,40,239,145,16,61,2,21,53,225,151,42,46,178,254,172,121,146,229,65,205,191,39,191,0,87,190,46,191,22,123,200,139,113,94,174,247,176,240,205,238,29,168,29,60,236,190,105,89,250,98,16,22,29,7,98,249,211,176,242,209,100,89,245,171,115,110,200,111,242,183,201,155,136,222,13,227,9,253,36,112,138,195,186,153,148,232,95,157,254,93,114,241,79,80,57,177,111,57,4,237,165,191,139,164,81,3,207,183,138,184,215,177,14,235,71,40,128,23,185,56,40,183,212,222,72,101,191,33,31,249,226,62,202,195,11,33,42,49,224,43,173,74,123,119,186,51,85,190,107,18,48,56,1,12,127,179,208,33,127,241,225,155,46,102,210,102,62,252,115,120,26,226,122,3,217,143,41,132,42,120,233,82,238,211,135,225,123,156,2,4,149,221,138,104,147,123,234,11,205,211,93,7,175,129,127,42,214,118,62,1,53,35,156,81,87,121,161,22,190,87,86,230,158,202,9,134,236,26,81,191,18,142,223,63,92,53,93,23,192,14,157,8,3,231,204,141,185,149,222,214,164,219,189,116,143,247,49,14,201,169,127,118,91,188,247,96,199,226,122,10,237,149,176,122,254,243,125,142,175,247,145,71,19,166,128,29,198,27,151,127,116,84,23,222,180,246,55,204,53,225,151,254,242,89,2,57,250,32,108,76,198,104,125,101,197,167,188,144,162,161,59,133,192,42,110,149,191,96,18,45,248,169,122,191,156,232,42,174,157,127,137,237,193,174,189,159,8,254,15,242,108,200,171,5,62,68,81,56,173,134,123,100,96,11,89,50,134,253,172,8,79,194,241,48,109,126,159,167,38,0,221,124,130,83,150,199,6,7,183,3,197,234,78,151,201,75,50,240,165,13,203,215,1,244,84,183,188,124,160,115,250,21,233,22,239,208,36,199,19,228,204,213,53,87,17,10,153,231,91,16,53,132,66,114,81,178,89,84,244,160,63,145,38,216,145,246,155,203,97,42,73,123,239,210,135,205,130,22,253,208,106,120,129,112,137,94,8,228,242,217,210,226,38,210,82,201,122,175,72,50,42,163,7,51,102,154,111,196,253,255,93,250,22,36,213,2,6,46,200,255,129,185,133,204,93,223,5,132,25,18,175,137,211,7,243,219,223,232,188,72,87,127,36,237,56,199,36,154,182,134,84,221,100,54,103,23,243,229,23,196,122,35,192,184,147,171,76,116,74,142,151,187,110,51,176,156,165,34,19,53,152,88,182,164,95,127,132,213,148,140,203,253,139,249,79,11,60,20,71,69,169,72,123,193,22,111,214,186,102,170,211,168,148,49,227,129,205,57,165,71,140,40,150,234,73,126,200,35,211,192,236,215,18,42,136,226,1,16,175,88,171,239,99,184,245,61,90,218,79,72,214,3,28,113,21,62,7,135,133,223,79,212,184,190,112,5,164,34,99,112,170,0,173,143,233,225,133,74,23,122,48,173,223,165,156,165,187,74,118,43,109,126,143,126,233,80,54,105,231,146,3,91,202,238,249,104,233,213,218,141,222,210,165,72,170,201,15,87,4,10,244,163,223,220,212,242,120,68,247,243,90,249,167,242,174,149,203,197,222,92,200,223,63,91,122,149,74,141,168,170,203,189,100,16,69,15,202,11,60,174,30,237,151,152,177,139,21,216,192,176,47,239,124,156,175,215,137,240,241,253,188,94,158,118,97,221,85,40,21,119,180,85,20,188,144,213,252,17,154,251,240,192,68,167,189,252,156,159,112,45,30,22,112,166,86,89,211,231,152,208,10,43,110,229,47,93,213,17,106,39,169,192,138,239,219,231,252,156,190,150,251,138,110,81,59,227,53,174,226,15,16,223,74,136,81,23,18,58,60,127,91,9,247,16,189,14,205,201,32,33,158,15,219,239,65,38,0,93,167,245,163,47,36,184,41,29,23,110,21,13,156,207,25,154,180,100,84,221,85,194,87,146,23,205,247,25,112,110,63,45,91,224,142,137,255,64,51,17,15,82,139,183,105,155,156,201,28,18,21,112,220,143,204,126,180,89,244,104,183,38,71,58,21,213,156,23,55,235,174,75,175,111,200,204,223,24,197,20,166,184,84,243,3,153,253,28,154,46,74,249,182,17,11,13,231,114,131,158,58,58,212,14,179,105,128,213,78,211,216,4,190,33,151,77,157,223,150,183,214,33,115,83,125,214,10,213,162,228,94,196,252,48,162,255,134,119,43,208,96,120,106,123,153,217,229,195,191,27,237,198,175,254,47,157,59,43,172,78,207,246,71,46,251,233,234,83,21,54,89,224,119,2,223,171,249,159,27,164,87,49,97,207,245,222,132,232,248,90,101,143,219,59,240,128,119,31,49,164,132,159,68,179,173,98,229,196,86,237,78,80,8,166,216,228,22,113,157,243,110,200,30,156,81,6,233,189,114,190,124,183,96,135,227,233,244,67,39,111,218,42,133,223,239,206,20,39,29,133,68,8,146,69,22,94,87,104,251,189,71,198,161,189,110,82,254,255,170,236,187,67,25,7,63,30,187,40,155,155,67,224,102,245,142,81,117,191,47,218,221,49,149,244,63,234,230,22,165,215,32,122,53,116,196,80,5,248,160,197,89,201,229,26,202,148,32,164,196,9,42,138,169,128,205,72,31,105,205,250,118,40,82,99,153,122,159,84,143,164,72,54,239,148,53,127,226,166,246,124,179,134,81,78,3,15,90,9,119,228,78,164,223,123,109,132,147,230,48,6,174,65,238,153,102,220,178,241,207,11,40,193,225,115,118,226,193,38,103,60,169,224,50,92,51,119,136,81,202,15,212,95,153,192,246,139,76,50,211,2,3,95,17,223,8,97,151,178,253,38,216,33,173,168,227,244,133,164,96,199,107,108,238,51,71,42,26,229,45,100,95,83,68,107,196,143,122,197,68,159,124,237,164,23,235,46,165,80,45,163,207,107,47,126,220,209,100,44,58,215,35,27,223,194,1,193,98,7,39,78,139,103,203,33,190,253,167,157,17,103,217,33,104,169,80,174,220,75,250,8,219,225,168,89,48,227,197,82,22,103,251,3,239,157,108,86,174,143,70,87,109,65,198,73,77,195,212,119,94,182,57,65,139,33,31,244,128,196,41,36,245,195,132,207,76,195,101,200,43,227,49,96,198,20,82,69,176,102,180,35,24,18,89,33,244,88,224,223,213,128,41,107,154,152,150,215,137,89,177,252,30,199,199,47,90,116,58,5,112,46,35,151,81,68,249,242,167,226,197,170,93,203,85,146,38,237,12,188,233,112,159,52,77,58,104,6,157,114,39,245,152,252,158,115,175,214,15,232,74,206,54,73,71,234,60,51,14,47,123,120,250,201,200,123,216,171,180,244,227,5,188,44,130,131,111,3,233,165,207,54,44,199,24,113,216,193,244,92,118,128,183,237,236,186,4,164,213,211,218,108,158,19,138,159,145,129,92,156,244,175,53,86,120,162,85,247,201,199,10,214,136,52,48,63,61,216,176,246,233,230,250,5,240,148,171,187,132,143,166,206,165,249,123,155,148,204,159,8,191,20,132,129,65,127,70,69,232,132,100,238,50,212,60,113,121,177,41,86,246,127,211,240,33,206,165,171,93,76,236,217,135,29,0,166,187,178,39,237,55,163,186,191,191,211,56,92,186,22,148,108,73,30,103,146,9,72,23,61,17,162,27,101,49,87,220,39,234,124,212,132,41,3,78,150,25,170,95,49,119,0,234,71,65,146,68,216,187,168,13,21,175,165,136,181,210,106,157,53,208,113,130,244,238,22,77,205,5,13,196,199,181,158,205,234,6,255,134,102,111,67,246,144,87,32,180,150,152,233,204,245,43,44,11,25,86,89,12,25,150,158,74,48,125,131,147,195,59,47,162,175,130,34,173,3,201,251,3,237,81,218,199,206,23,172,77,14,239,186,1,43,173,2,147,146,136,82,58,47,18,145,130,33,199,127,30,164,194,197,38,199,215,205,142,26,64,202,79,161,177,66,124,209,155,168,3,114,218,105,230,42,202,235,142,209,222,119,104,143,26,113,41,90,45,254,70,183,168,43,42,137,143,187,239,9,8,178,62,182,203,39,200,57,187,61,57,192,250,244,104,103,171,215,34,125,232,34,155,231,203,97,231,33,66,169,40,88,236,8,171,61,148,249,250,13,11,226,193,198,123,31,26,149,146,96,223,54,233,113,212,205,77,56,8,61,148,247,52,180,228,140,72,86,218,168,88,8,156,251,243,178,125,74,91,45,158,99,16,123,204,125,113,43,210,245,209,131,23,134,206,102,54,1,142,231,87,195,174,181,239,239,86,163,235,100,237,81,63,7,216,71,57,243,174,46,41,198,204,23,36,30,146,244,6,1,184,190,19,63,42,46,100,56,204,224,123,41,226,131,235,231,240,155,99,109,209,12,100,104,50,255,72,219,122,161,90,212,60,106,227,74,10,89,186,113,237,179,83,196,238,119,141,104,114,173,179,86,178,17,69,110,207,30,151,36,68,194,212,89,233,82,192,45,147,178,66,190,115,22,176,165,173,186,81,160,197,14,204,114,96,224,78,44,255,53,141,95,141,35,87,21,2,119,167,87,148,157,0,3,7,4,189,143,246,0,75,49,208,53,167,176,64,97,231,187,92,188,62,82,45,135,127,19,213,154,100,24,56,110,201,180,127,48,181,9,89,127,242,229,193,151,86,191,97,165,162,195,1,166,210,18,89,251,158,24,134,83,245,135,40,71,204,186,236,214,65,136,75,197,21,169,134,219,218,167,20,44,2,230,25,206,230,54,252,60,177,200,123,246,253,65,232,206,31,44,166,98,32,5,68,217,125,228,71,159,18,54,190,28,246,164,213,29,174,134,239,237,152,5,51,209,185,115,135,144,213,4,198,117,62,48,199,181,191,186,45,227,138,188,103,172,145,247,249,127,74,124,87,157,200,232,27,201,34,228,120,131,249,156,115,37,81,184,247,46,253,213,80,162,195,181,24,216,225,161,44,39,35,175,207,245,157,148,136,165,117,42,219,243,88,122,49,192,168,204,131,187,189,193,252,131,50,134,224,105,205,82,118,64,251,240,245,82,107,107,218,180,33,102,58,170,217,211,110,142,245,245,96,91,18,114,65,209,188,251,89,18,181,167,49,32,141,214,43,221,86,35,10,136,104,47,107,217,124,64,90,207,11,155,53,224,147,244,194,204,133,178,53,159,168,170,30,45,106,80,163,115,161,243,6,231,103,81,117,40,211,183,179,236,124,82,111,181,169,46,65,124,13,52,169,192,37,207,172,57,133,183,210,142,180,86,0,248,141,193,19,10,38,12,133,241,40,49,33,205,100,148,224,188,56,231,220,78,63,120,148,76,220,172,148,60,170,63,253,125,101,78,225,173,164,29,201,29,153,151,19,76,164,6,98,135,96,213,44,246,178,230,179,221,115,152,90,88,99,123,157,185,189,44,105,242,219,81,16,122,79,241,232,242,165,155,212,229,170,111,12,84,168,198,206,249,142,55,201,171,153,102,63,166,23,97,225,31,49,91,167,25,41,241,152,104,33,80,167,137,215,240,39,127,145,7,89,181,242,2,169,20,24,141,0,171,27,121,198,55,163,188,83,26,237,37,213,146,126,111,121,186,119,40,176,83,252,58,148,84,216,104,255,38,197,102,76,167,73,220,60,238,67,255,207,91,81,228,58,112,32,121,40,207,110,187,118,202,6,199,242,180,76,240,99,209,182,38,204,189,90,78,186,57,155,29,47,48,2,47,38,215,13,11,37,44,205,1,19,223,33,143,9,158,197,48,36,5,95,114,127,115,41,5,43,188,229,156,86,120,230,46,251,245,39,178,91,38,120,191,102,204,32,215,72,239,157,194,172,38,135,154,3,134,178,31,180,231,88,186,187,220,207,235,187,177,179,47,213,188,251,208,242,18,102,186,145,176,24,166,38,6,69,229,255,131,71,167,8,35,171,18,164,154,122,159,217,77,112,136,198,6,69,119,236,237,148,31,41,255,52,61,241,170,236,190,41,166,171,87,48,18,3,163,126,168,103,42,187,25,182,18,47,186,251,197,62,185,210,216,64,233,238,118,229,203,247,93,47,146,49,76,62,216,229,0,252,97,39,135,217,122,206,25,58,4,251,244,237,112,152,24,11,127,12,20,169,37,182,221,104,241,196,89,64,184,157,132,124,145,191,249,154,95,71,31,24,245,3,174,191,135,16,11,1,52,19,108,234,196,203,76,14,236,21,23,123,39,109,156,247,86,154,21,210,236,104,157,21,25,164,105,124,137,12,1,91,150,193,242,55,157,100,102,83,3,73,226,223,162,92,132,68,244,80,35,25,137,229,72,234,172,35,37,23,3,23,207,218,68,11,119,251,54,113,197,111,104,143,160,164,62,63,180,50,219,178,207,67,168,117,175,157,84,14,106,107,193,190,20,83,207,167,144,179,0,26,81,91,229,108,45,213,131,114,58,85,223,125,19,50,72,20,200,123,194,206,164,43,213,248,234,104,65,133,55,198,20,226,33,191,118,251,225,19,27,242,34,39,18,66,232,21,134,55,228,145,223,95,55,168,200,135,3,121,31,234,221,237,177,166,103,44,181,203,242,108,18,27,30,58,29,84,222,121,96,66,193,136,21,101,187,33,169,167,229,106,64,128,237,180,119,39,91,196,196,75,135,247,119,61,23,184,122,30,197,125,130,173,19,138,71,2,23,67,138,126,199,10,91,128,181,238,24,39,168,143,155,242,194,192,127,158,166,39,51,199,181,203,221,253,110,214,163,111,220,242,226,255,72,47,219,208,235,247,25,3,110,193,15,191,92,71,103,115,44,31,190,183,108,33,11,11,116,136,94,34,254,76,25,120,255,157,47,32,56,142,225,113,226,199,190,157,184,131,71,225,130,112,197,214,195,206,30,8,7,246,151,49,35,167,154,231,212,36,108,195,43,185,70,209,38,34,69,125,105,123,119,211,120,184,218,166,53,76,69,247,156,120,88,195,69,165,161,23,195,218,119,76,76,66,104,59,139,39,185,243,39,139,244,98,234,46,23,159,68,190,188,244,234,129,240,182,168,158,78,239,255,92,0,175,181,253,95,101,115,134,117,131,242,203,203,149,223,61,126,84,190,74,28,225,28,169,188,173,201,148,178,88,114,34,34,114,241,137,110,163,206,115,240,243,231,205,141,4,26,233,79,45,33,36,55,139,110,43,100,191,21,153,51,143,221,173,222,81,194,84,19,148,73,165,1,120,32,55,13,6,169,112,22,132,245,186,97,91,251,127,118,197,159,44,111,194,35,235,55,104,83,59,229,21,186,180,245,1,211,250,70,246,175,193,173,3,10,211,11,53,62,173,127,204,107,31,90,107,23,46,125,208,124,56,245,163,163,57,103,7,233,58,246,108,174,229,171,23,232,102,119,122,200,213,184,250,117,108,235,241,187,161,176,179,75,205,88,60,223,222,49,2,226,14,162,12,77,40,4,19,93,158,238,47,224,205,224,7,49,131,185,71,239,213,168,135,20,60,1,75,73,173,237,228,75,129,202,168,178,101,107,23,212,208,252,64,120,215,230,189,30,90,173,25,36,52,153,121,119,244,0,218,221,163,247,120,60,38,185,221,146,188,150,132,84,167,77,146,213,42,207,17,144,121,181,76,144,251,231,95,128,14,137,122,63,6,169,150,195,39,205,228,227,1,143,187,78,252,85,91,78,141,15,5,188,74,113,210,7,143,250,87,57,255,213,121,240,53,19,87,18,120,198,123,63,24,198,228,92,232,72,105,48,12,207,207,17,106,59,108,144,93,141,98,2,28,182,176,70,28,247,137,122,236,54,84,126,41,181,216,139,129,247,34,46,163,249,240,136,103,236,74,65,133,208,181,229,93,4,24,122,172,106,38,116,211,252,51,246,245,125,174,132,25,201,164,126,24,78,192,236,219,205,15,173,33,179,66,25,177,137,160,220,106,64,24,39,167,32,84,134,18,132,36,229,240,69,30,247,89,251,237,201,7,14,201,79,189,110,174,243,72,122,148,168,224,181,104,181,118,185,251,15,151,87,21,55,103,241,50,78,230,130,209,86,159,156,170,94,144,138,58,126,207,11,54,7,245,59,243,114,223,219,201,19,217,56,26,202,86,26,0,209,33,120,188,194,126,55,240,25,217,138,78,17,167,243,13,4,21,105,179,127,47,244,166,169,226,61,6,226,233,126,135,171,181,30,102,190,208,255,240,182,154,143,97,212,68,186,249,89,179,97,92,213,46,93,212,3,123,51,245,158,155,123,252,73,103,51,206,136,90,30,98,190,174,217,221,32,175,183,73,109,26,244,221,117,82,5,122,151,210,89,151,11,210,22,105,117,99,230,46,222,146,229,8,37,226,19,117,234,100,178,179,14,139,47,254,248,56,31,130,253,152,194,19,223,191,170,171,253,242,248,67,34,229,231,192,107,167,251,229,176,32,199,210,76,27,232,173,199,201,7,17,7,97,5,47,18,94,188,208,240,184,35,90,222,240,67,14,151,222,115,12,233,140,243,31,148,69,221,192,40,175,42,209,176,104,218,24,155,174,150,65,70,186,149,252,62,247,127,78,90,130,121,62,61,35,171,183,121,104,223,221,204,53,145,251,37,195,208,195,78,192,52,7,244,48,90,168,116,77,76,133,102,100,187,188,154,112,11,66,154,157,154,191,159,121,230,108,27,118,146,83,240,131,49,36,240,195,5,132,210,166,136,120,116,52,84,235,187,216,213,127,172,121,133,222,233,254,255,221,44,163,2,142,228,176,2,242,22,240,196,194,141,61,67,189,1,128,158,99,205,104,148,144,245,168,164,253,133,129,79,252,89,163,92,28,10,15,110,104,221,150,53,14,150,169,49,228,39,135,2,131,27,78,255,126,250,187,163,109,81,248,54,254,20,115,88,132,185,229,60,234,16,116,174,132,157,253,229,5,131,107,14,189,199,36,210,232,131,168,221,110,88,228,199,93,131,89,37,110,40,199,250,105,176,31,21,73,222,34,236,161,48,84,213,68,141,187,5,144,182,224,240,174,196,146,235,153,165,13,201,185,183,147,103,225,143,126,107,95,216,177,239,110,24,158,174,26,250,215,157,47,174,166,100,231,110,109,120,32,54,152,241,160,172,86,26,182,109,117,43,215,116,247,228,76,123,134,56,212,157,49,5,95,250,128,179,169,164,225,38,192,51,74,95,100,79,27,57,90,23,164,104,232,4,10,27,254,133,7,204,99,182,182,254,10,140,236,247,214,36,137,240,201,219,32,188,25,15,105,35,138,221,90,83,32,222,57,184,70,75,92,151,44,3,93,185,215,150,49,77,11,52,167,70,166,206,15,95,95,34,176,23,103,3,148,221,131,29,66,83,169,104,134,104,70,182,170,183,229,173,147,49,28,224,45,62,19,45,157,232,140,109,186,88,78,247,218,57,63,206,253,190,254,26,73,200,249,104,102,169,125,172,129,152,230,207,60,242,242,131,107,77,213,104,160,74,183,93,106,137,248,0,160,170,180,133,106,116,44,112,70,148,20,20,151,172,207,128,133,253,140,156,219,38,15,176,137,168,40,39,31,159,215,155,86,29,15,65,121,247,136,121,39,127,11,112,152,6,87,191,80,157,11,53,2,60,14,90,193,100,21,117,114,69,152,85,76,87,118,240,232,17,219,173,199,255,216,117,116,69,185,78,185,185,186,80,99,210,212,163,238,103,235,91,10,82,19,48,102,167,207,167,123,99,83,249,245,101,136,168,179,105,38,142,100,123,248,6,23,170,138,133,80,221,212,212,80,228,81,14,149,190,241,40,125,29,47,20,165,142,224,27,176,121,240,90,107,47,78,61,163,178,51,134,109,46,144,156,89,166,61,66,29,209,184,111,95,222,188,175,12,49,240,217,121,232,135,25,62,150,30,232,57,246,215,250,38,2,83,242,252,190,51,86,4,167,8,175,107,112,218,184,49,150,194,190,15,68,107,170,121,164,220,187,114,229,189,130,197,172,228,41,45,39,197,227,142,189,102,76,26,129,166,150,81,105,139,90,77,30,49,4,114,115,184,251,179,83,152,78,234,65,212,35,56,112,76,94,139,184,209,43,12,63,225,49,202,81,14,152,125,70,197,226,208,171,16,169,114,109,158,150,211,196,63,94,80,92,150,76,11,96,101,221,241,44,211,91,248,129,195,145,88,145,111,161,163,213,230,49,142,160,231,8,178,110,242,175,228,136,216,212,20,19,25,173,166,118,68,51,205,253,42,202,181,200,48,90,164,60,185,176,139,195,17,160,191,192,233,113,145,204,187,178,23,121,222,227,111,229,253,119,207,96,177,28,29,245,123,92,17,29,240,86,87,62,88,149,238,3,94,148,231,26,145,225,93,17,39,120,224,186,250,155,247,13,56,143,69,29,187,113,230,179,85,70,132,193,173,204,235,33,192,221,10,32,163,16,208,104,37,179,131,10,191,211,139,5,131,134,154,169,138,21,225,61,229,52,12,60,120,101,95,57,112,251,13,132,60,201,17,116,68,190,190,26,185,203,47,208,128,179,183,50,39,7,18,65,103,245,76,123,224,204,244,114,221,69,91,235,230,128,122,56,108,191,4,95,142,36,166,82,144,24,140,3,228,108,241,174,130,231,202,72,112,73,141,7,127,113,230,245,197,112,87,123,105,74,134,53,76,145,42,251,133,251,214,190,38,162,169,29,72,89,63,152,102,162,46,87,7,30,18,59,87,139,199,206,30,65,251,254,94,194,119,105,18,246,106,119,64,220,186,134,11,167,83,59,149,225,125,47,110,114,196,226,63,216,255,90,195,7,253,107,232,220,141,0,124,120,115,183,35,194,113,216,189,121,235,55,6,215,187,122,35,48,10,153,153,34,253,25,219,105,240,1,1,211,194,195,234,190,184,252,245,97,59,105,30,99,40,52,200,113,27,43,2,87,95,145,106,184,240,162,115,81,12,210,126,2,145,123,11,93,58,39,227,208,40,214,20,231,189,61,47,24,41,112,160,236,175,94,238,184,152,106,155,126,150,7,27,75,184,241,220,152,200,217,212,239,0,215,175,13,134,249,207,102,216,20,173,188,230,55,124,95,195,224,223,4,219,88,209,5,153,54,22,239,59,237,255,88,214,198,148,198,1,81,190,171,231,153,188,26,227,221,105,42,129,175,234,114,160,231,91,31,200,246,173,2,178,36,28,61,128,216,158,252,168,85,71,47,223,241,171,81,83,189,50,59,92,27,193,49,245,178,37,202,198,134,13,121,247,47,207,37,26,25,77,115,200,81,9,26,214,169,92,111,5,30,227,119,166,48,109,199,233,210,138,70,22,212,57,36,37,43,135,54,131,51,116,82,189,87,205,43,164,194,175,123,111,193,15,173,166,224,73,38,222,151,152,64,214,30,197,78,145,241,115,94,210,143,158,105,89,171,162,171,135,85,7,246,91,9,54,124,143,153,117,159,28,61,87,117,155,91,197,86,162,191,201,143,57,11,249,111,117,217,131,153,150,35,20,202,32,52,42,197,123,23,82,25,127,93,52,212,252,172,232,35,134,59,94,68,176,70,173,77,233,79,157,138,70,36,119,60,113,32,111,255,169,194,221,153,71,116,105,149,100,131,127,151,16,200,246,115,252,222,245,156,138,82,10,46,23,131,132,193,72,187,206,160,232,182,135,59,250,14,238,51,62,75,202,158,11,16,30,93,250,160,198,252,236,193,100,76,159,18,141,140,230,117,110,174,224,34,234,218,94,101,142,5,0,71,214,59,190,200,102,83,244,99,255,46,247,39,169,223,121,43,60,47,188,188,208,36,197,129,217,142,125,136,79,124,116,219,126,249,201,160,28,145,149,180,144,94,217,45,123,150,151,182,6,201,0,9,40,251,87,84,218,163,222,45,207,244,132,245,232,74,183,57,28,116,94,43,154,243,147,251,146,74,8,91,196,121,218,183,133,47,134,204,177,84,101,160,250,228,0,148,77,237,122,177,119,186,116,212,61,47,248,108,8,54,39,246,109,71,152,121,60,7,155,59,146,70,57,144,149,192,225,180,130,129,180,21,254,58,241,74,7,145,4,95,98,179,10,166,106,238,247,235,189,253,123,23,1,99,69,97,171,158,55,243,220,133,110,211,145,82,46,36,54,248,72,76,195,3,126,139,255,119,198,53,237,204,240,12,16,36,136,152,89,226,221,173,26,128,174,124,60,14,101,240,14,223,190,236,215,181,142,226,136,57,139,125,199,19,233,237,52,240,81,8,72,198,177,235,104,93,197,212,150,57,233,205,162,164,240,170,151,194,7,63,68,60,61,94,150,62,214,214,145,179,122,105,136,249,188,77,91,144,150,170,29,112,185,234,107,230,8,56,59,193,238,25,67,154,92,50,137,72,92,195,136,204,210,248,244,251,78,120,15,70,164,121,131,35,115,166,196,207,41,202,227,31,144,154,246,104,143,9,68,163,47,127,121,217,117,144,150,0,128,193,213,40,211,209,98,101,29,140,108,124,174,180,115,136,217,244,39,187,206,214,11,27,63,230,114,118,96,18,25,121,164,145,122,105,91,79,178,150,142,25,230,209,80,40,65,224,165,21,141,214,68,108,14,92,95,7,73,23,104,140,18,96,187,126,120,52,134,184,40,56,133,198,19,15,91,131,166,21,209,52,111,67,144,106,96,103,116,245,31,109,244,34,215,2,53,67,218,252,189,151,186,64,252,122,242,138,240,73,107,24,161,26,180,112,36,146,49,230,134,181,122,231,34,99,66,155,35,28,99,141,17,196,80,183,14,19,5,108,202,192,116,226,90,96,106,251,246,68,9,101,78,173,182,182,150,26,120,252,69,214,30,191,67,184,210,240,126,26,135,6,121,73,183,17,127,176,241,41,12,102,126,158,227,233,94,221,207,150,58,8,176,71,37,107,70,188,166,123,168,36,181,128,139,5,145,239,28,152,174,101,0,244,177,132,116,226,16,188,45,130,212,244,240,235,163,184,192,159,46,86,85,14,241,210,74,168,3,166,35,250,13,181,48,252,252,58,206,162,198,37,69,141,114,50,182,120,147,24,24,65,194,239,5,53,178,58,45,41,70,7,239,170,222,28,182,248,46,148,253,98,53,34,32,41,104,231,118,150,107,161,225,45,99,83,251,10,117,205,246,108,109,232,152,30,186,234,24,156,240,48,227,97,50,229,139,7,237,123,52,251,195,225,39,51,144,228,99,91,252,238,140,20,136,56,36,192,171,128,79,191,194,163,114,19,75,162,251,29,55,229,4,124,21,245,48,3,117,182,93,82,222,228,190,130,67,55,248,172,146,103,215,50,217,23,63,162,239,61,168,212,203,7,172,243,33,13,199,93,158,97,45,29,13,142,204,172,124,180,102,30,228,49,135,47,127,224,118,63,217,116,47,158,235,123,151,230,14,103,73,3,193,208,33,196,99,53,41,240,165,255,220,200,97,116,5,83,0,124,132,245,111,141,255,198,152,240,87,46,154,61,208,44,215,91,87,154,24,152,39,28,252,37,238,10,16,57,123,117,238,217,13,196,199,74,22,14,120,81,27,17,74,173,183,121,3,86,82,6,131,82,134,117,29,121,158,183,251,70,244,48,95,107,148,237,77,82,127,144,16,16,218,127,211,152,214,195,182,179,215,143,161,154,101,43,14,35,250,203,253,64,129,84,41,4,109,130,48,216,78,240,126,226,99,122,41,151,99,62,36,161,149,46,250,165,208,193,84,26,104,110,149,182,155,10,95,38,105,202,49,30,29,127,8,217,255,129,32,215,179,241,0,249,121,62,179,196,135,132,200,158,97,11,14,185,97,208,61,161,36,172,67,75,172,150,248,254,104,3,119,178,210,103,248,98,213,14,108,118,14,179,195,152,103,5,186,114,48,95,80,237,209,133,194,2,26,176,166,94,176,45,148,91,40,190,178,83,84,127,177,144,186,174,203,189,170,42,136,63,199,249,224,249,100,186,110,74,103,195,15,24,213,146,46,235,158,226,238,239,55,227,156,90,46,97,184,116,74,118,227,86,13,42,246,213,66,21,220,96,18,25,82,85,91,182,184,191,126,99,30,203,243,141,147,94,255,108,249,128,219,182,229,205,94,52,141,185,113,4,26,182,202,199,183,107,243,96,25,229,37,212,26,243,213,160,52,64,134,213,93,51,6,94,101,39,220,51,29,23,221,179,239,79,58,152,40,66,230,156,229,34,235,179,168,4,88,123,73,71,198,10,191,87,227,62,24,191,207,65,238,100,223,193,124,131,101,203,67,41,200,115,140,224,0,128,183,42,7,104,153,50,191,127,109,115,242,79,22,204,210,46,8,119,224,10,28,166,91,38,72,17,235,203,23,216,20,231,255,245,222,234,58,127,44,81,56,42,144,153,190,130,25,86,230,181,33,214,139,38,199,240,81,247,126,229,211,101,195,124,73,136,72,248,234,99,246,105,154,73,73,207,67,186,180,202,212,123,250,179,78,60,213,85,34,164,241,102,197,181,142,97,65,219,222,105,172,176,18,42,163,1,108,246,35,177,96,217,153,120,184,76,173,175,198,154,230,38,63,82,115,189,143,197,236,55,52,53,41,175,178,150,221,26,68,109,30,214,140,25,164,202,186,4,217,238,23,168,82,167,111,100,190,145,78,47,126,243,159,138,184,251,159,87,251,174,117,186,228,255,15,108,122,171,51,55,228,93,120,49,124,44,251,139,52,118,61,130,94,242,73,120,11,150,17,96,107,16,102,39,178,100,163,192,250,158,155,244,235,169,131,88,213,223,85,122,8,168,243,80,219,116,146,175,159,62,35,43,135,148,21,66,25,179,109,127,221,236,36,111,160,212,171,7,92,127,176,179,88,157,41,60,157,142,243,154,42,211,76,123,121,136,229,151,108,96,152,151,221,143,164,201,195,206,3,110,221,247,230,10,22,184,135,8,143,17,144,163,190,196,224,200,247,157,192,229,48,101,86,208,207,240,215,139,31,201,193,124,238,195,126,71,35,171,199,55,31,250,140,222,224,135,165,83,72,4,100,242,1,75,183,145,215,131,34,93,56,111,51,53,106,230,117,63,11,102,237,240,122,66,42,117,192,4,86,49,0,53,61,87,127,200,166,154,42,251,104,187,124,138,44,139,120,102,8,82,3,81,22,205,90,61,62,227,186,145,77,163,201,57,190,151,135,149,230,33,101,212,104,202,174,54,166,142,45,184,185,101,190,178,41,240,245,246,86,53,132,202,29,134,142,125,241,104,199,151,132,220,7,103,174,222,130,222,192,128,222,244,248,175,184,210,11,155,113,55,159,85,102,114,86,226,246,104,217,4,24,43,99,30,70,54,129,59,8,148,168,127,112,190,36,250,195,229,230,32,243,41,72,142,75,60,138,255,18,244,201,143,138,136,221,128,179,206,208,56,107,3,134,64,117,219,225,108,165,47,19,245,51,153,55,66,143,251,68,247,198,104,68,120,146,81,110,240,74,124,32,249,8,165,120,121,44,153,89,142,143,206,241,184,126,38,59,213,224,231,15,230,193,110,93,229,157,201,63,126,60,164,174,235,96,185,140,74,23,216,231,202,130,129,211,165,104,142,217,255,63,141,232,107,222,252,145,144,216,242,56,114,109,58,206,254,235,21,233,150,138,180,215,109,20,131,219,73,166,132,176,214,223,47,25,158,218,18,152,123,111,215,132,205,167,253,223,10,137,239,239,88,14,243,51,218,110,240,39,87,94,78,104,53,167,103,189,172,115,100,94,232,135,143,101,134,112,12,215,150,62,103,77,42,193,118,182,113,184,37,72,2,228,136,197,29,193,212,149,88,14,192,3,86,75,233,84,177,151,76,244,63,160,193,203,22,70,20,56,48,28,172,236,92,37,163,18,218,223,23,182,69,142,150,49,143,237,108,131,72,236,122,116,211,38,50,115,181,115,12,65,194,96,229,61,1,5,220,47,212,110,238,156,103,133,115,145,154,93,73,134,100,45,103,62,106,54,239,75,186,223,190,54,208,131,170,150,108,221,66,245,185,245,152,113,3,247,236,170,246,41,121,215,121,207,110,240,66,211,118,61,242,121,210,59,143,188,126,3,37,146,154,194,209,230,151,75,254,147,205,160,56,243,87,113,96,207,161,126,46,252,110,42,172,58,62,53,89,23,123,99,221,183,135,3,253,45,192,39,108,86,5,227,204,55,25,171,225,60,119,110,14,86,190,225,62,48,135,65,66,119,232,154,47,13,204,55,14,196,242,135,81,117,133,71,144,52,140,215,244,229,193,201,179,53,110,169,68,133,196,191,84,223,33,132,109,203,185,133,33,242,255,177,245,214,81,81,126,221,251,176,32,82,130,48,2,210,12,13,210,37,13,67,163,210,138,132,40,33,221,2,210,49,32,221,160,72,195,16,34,37,37,157,163,116,135,116,14,221,141,228,212,187,16,62,191,239,243,124,158,119,173,243,135,107,201,90,115,223,103,239,125,237,107,239,115,238,125,77,82,146,121,83,196,70,248,6,109,12,173,172,196,239,171,194,129,130,251,154,59,11,205,157,58,37,175,151,234,191,73,157,21,216,183,123,86,111,188,254,227,167,182,66,175,95,51,228,119,84,146,20,243,103,27,108,231,224,253,10,149,96,164,7,101,188,2,4,116,98,57,52,224,193,222,180,213,218,204,84,219,90,82,139,56,168,198,143,104,24,188,170,173,57,0,163,225,209,130,86,26,88,169,0,140,7,59,239,221,79,224,47,5,197,185,51,158,223,3,212,93,109,23,239,21,27,33,109,152,40,35,45,186,116,54,120,239,63,235,76,228,153,208,183,204,48,223,153,116,188,147,230,85,12,123,24,248,91,18,37,181,182,250,50,10,150,249,73,226,61,86,47,4,74,52,167,85,96,1,32,14,200,96,161,15,28,30,252,244,66,252,166,175,249,77,214,159,232,192,71,233,16,132,120,15,131,124,223,220,80,159,9,13,221,146,12,139,176,50,195,3,63,48,19,183,8,50,141,227,204,149,122,133,31,246,163,168,232,72,239,35,66,255,89,159,92,147,116,89,183,96,77,242,21,196,231,176,37,170,47,69,45,213,231,83,229,204,75,212,215,65,206,197,224,6,80,221,149,235,116,4,122,249,222,9,242,117,103,236,180,139,32,164,70,165,5,110,94,220,70,189,63,205,93,148,97,73,52,239,157,54,239,189,67,120,134,68,95,148,128,209,161,174,187,253,167,26,220,152,133,241,129,161,1,108,35,231,25,206,201,224,208,156,22,233,1,179,231,100,174,187,83,211,210,136,45,222,41,56,200,73,122,38,149,173,198,61,19,126,212,74,223,46,190,69,87,183,83,230,70,65,160,84,239,199,115,255,124,121,151,50,44,220,197,162,161,18,118,98,210,136,138,48,18,244,116,198,61,101,204,165,13,117,98,125,254,189,40,134,136,25,132,155,251,194,132,224,29,143,2,208,121,181,66,216,2,97,226,54,196,45,66,145,148,215,183,31,209,231,231,96,217,124,222,38,108,124,168,137,115,212,8,65,99,245,168,156,186,111,253,166,21,76,80,199,41,14,168,49,59,194,244,70,100,195,237,72,18,218,26,103,80,211,26,49,146,40,179,198,157,117,91,15,209,100,207,242,145,111,160,35,246,168,208,124,210,13,32,29,77,233,149,209,27,58,255,25,145,227,174,1,135,45,241,141,196,172,18,92,33,214,197,31,247,185,203,205,8,222,73,82,177,160,208,155,202,160,63,181,147,212,27,195,153,184,66,64,76,191,157,179,178,167,194,45,80,17,136,224,88,138,54,38,198,194,138,124,231,186,147,174,29,248,80,190,103,234,120,167,13,62,146,200,237,74,71,106,106,177,16,81,100,199,222,130,211,117,128,215,67,43,131,105,245,35,33,137,134,186,59,220,31,87,136,16,211,195,254,245,63,247,137,83,137,48,90,50,218,187,216,81,237,43,9,59,181,125,234,113,76,175,58,23,143,56,31,167,251,226,241,179,159,33,185,135,19,194,35,252,128,227,13,194,254,74,116,9,212,137,153,236,247,71,164,3,179,51,99,157,84,123,239,124,51,65,106,41,171,20,131,181,246,138,127,97,138,122,157,237,91,54,31,13,80,176,45,249,99,26,72,62,230,51,158,188,112,60,9,170,160,69,217,234,148,149,159,238,24,14,145,93,158,53,128,144,157,219,219,159,248,113,199,59,179,219,15,92,70,33,103,44,115,110,107,87,39,62,189,180,188,18,111,133,177,21,123,0,110,195,12,36,37,34,45,67,163,223,92,211,112,127,30,196,45,49,241,83,227,246,117,253,202,75,52,37,90,64,234,238,38,204,192,144,181,93,187,89,62,131,166,229,171,243,221,129,93,51,73,188,87,225,243,82,166,21,200,69,16,186,235,228,132,109,18,188,215,60,10,168,237,222,79,105,233,102,85,75,217,134,113,94,129,65,170,42,150,95,3,197,151,170,106,103,135,80,27,74,112,68,173,159,177,238,252,105,20,173,148,167,141,214,224,122,131,154,219,218,129,223,190,191,14,215,219,119,42,143,6,44,183,0,177,8,8,98,185,118,183,21,136,108,69,29,169,192,42,14,16,23,228,221,160,129,22,184,35,180,117,181,241,173,35,122,229,65,228,233,242,201,229,16,228,220,57,247,196,178,122,27,108,22,11,74,226,132,63,69,125,93,32,86,97,127,164,38,75,7,152,122,16,192,124,255,133,106,190,122,198,46,27,232,50,220,119,207,214,104,86,253,245,189,112,153,19,134,197,62,247,171,201,187,125,7,251,3,27,136,15,172,95,100,127,66,64,191,179,203,243,92,247,231,122,120,234,87,31,194,175,38,161,134,148,56,122,1,202,241,93,80,182,116,190,142,253,186,149,24,41,212,186,193,189,204,119,159,197,191,30,111,28,176,186,46,138,235,1,172,126,97,9,201,23,220,51,242,201,104,248,59,221,70,25,147,240,149,199,100,128,74,187,214,244,22,54,80,210,194,68,132,110,251,178,187,67,153,155,227,181,117,205,175,71,141,227,66,127,234,48,112,77,0,237,201,218,216,47,93,120,211,60,23,121,85,128,121,229,196,204,38,41,134,146,191,223,131,198,199,31,110,195,202,151,8,185,172,107,90,68,55,82,23,154,157,174,30,152,198,94,146,235,16,49,230,205,98,128,7,17,143,75,29,181,247,122,188,79,233,140,243,211,93,31,36,166,232,57,186,207,121,124,57,210,91,241,18,158,10,212,91,222,155,102,163,171,148,143,77,37,53,169,251,144,247,253,112,9,45,60,9,201,19,136,152,156,157,85,218,29,53,48,68,143,130,189,135,47,220,79,94,161,77,209,228,130,241,13,19,99,30,136,70,208,133,147,247,122,69,232,98,108,175,104,241,86,222,134,197,116,65,96,23,188,80,250,253,164,17,197,75,154,110,253,3,148,55,172,176,245,188,244,117,224,227,36,235,153,6,148,206,69,65,19,47,56,52,193,39,240,248,82,127,116,183,90,241,190,30,62,81,239,208,22,19,228,146,81,114,65,51,190,166,154,86,228,148,192,27,17,239,29,121,146,44,177,113,239,171,226,37,34,19,112,178,68,51,31,152,65,141,66,24,80,75,31,27,75,32,146,123,50,191,169,53,10,187,245,39,140,46,110,232,211,47,241,84,161,169,208,165,218,239,66,191,23,39,241,158,20,233,101,95,25,225,53,194,127,90,166,157,213,6,158,65,189,143,113,34,95,255,144,20,3,76,97,4,184,12,138,225,40,157,138,123,239,85,79,190,17,142,2,130,22,212,65,200,15,212,162,239,23,31,56,179,235,93,135,211,194,103,209,196,35,251,19,49,238,140,103,247,0,30,147,141,11,107,48,107,131,31,102,225,125,83,78,43,157,211,148,150,233,12,148,141,25,182,127,138,141,144,189,22,131,233,214,182,19,223,43,100,3,177,167,151,66,129,251,231,185,136,143,48,183,31,236,86,32,128,213,31,68,51,100,91,251,9,35,61,166,183,146,12,118,182,212,74,254,220,173,62,138,146,127,239,168,77,81,210,37,241,193,140,249,160,2,94,25,176,136,218,239,194,39,22,11,5,137,176,110,120,186,26,194,180,173,92,200,172,232,7,27,194,215,99,111,166,94,180,252,144,237,211,17,147,228,255,94,167,235,171,22,56,97,168,215,64,14,89,156,84,198,76,86,151,53,221,172,204,219,234,172,216,155,153,9,230,248,205,171,181,196,230,104,24,38,128,50,16,118,98,213,28,27,34,204,149,112,223,49,73,50,2,67,92,247,22,218,86,6,61,209,93,187,163,27,22,242,74,204,224,227,17,248,94,92,110,204,209,202,124,202,206,1,203,202,156,143,197,189,237,203,159,160,116,199,183,154,67,54,62,68,97,230,205,136,86,46,16,193,132,134,105,79,21,27,93,133,10,244,252,9,124,1,106,20,242,157,176,51,69,92,40,226,187,94,203,216,232,81,24,176,14,254,136,218,115,88,212,224,222,74,119,84,62,80,30,151,134,113,230,231,176,203,204,44,140,92,162,16,169,136,12,83,183,79,126,230,123,70,245,123,227,76,228,188,99,3,129,168,12,136,112,69,108,191,240,217,9,196,185,215,53,240,99,178,220,140,230,196,35,108,186,73,215,240,79,205,76,137,165,198,142,132,113,121,115,72,222,206,50,77,191,97,138,224,108,203,97,184,251,244,161,150,233,158,29,69,193,160,31,76,249,187,203,100,169,225,112,105,13,154,78,10,158,53,199,231,82,126,76,214,151,100,26,152,234,12,62,121,222,119,230,249,66,82,247,20,218,204,1,102,239,241,216,59,57,213,24,144,161,6,88,41,24,255,217,28,57,139,118,244,201,213,74,118,83,200,82,4,28,86,168,70,138,155,102,236,250,49,243,217,140,177,195,215,69,160,245,64,91,187,134,87,190,155,242,64,155,6,28,88,127,108,211,200,137,187,32,72,55,35,19,87,136,28,211,7,242,242,255,1,45,33,198,118,244,219,218,168,104,106,2,31,149,54,245,32,111,122,198,2,255,193,163,82,59,11,161,135,158,110,131,236,206,177,182,223,154,37,57,52,138,203,37,31,141,231,151,66,148,48,213,99,45,153,163,21,74,23,206,202,11,242,155,124,56,246,211,188,145,212,34,46,19,106,61,213,214,179,165,139,141,238,131,64,243,252,251,143,214,236,251,160,67,254,157,142,223,79,182,211,63,116,74,240,9,230,123,255,2,247,215,181,237,150,231,178,110,228,32,252,55,134,124,71,106,37,92,144,39,47,44,236,240,22,244,202,197,206,77,55,102,149,65,112,22,248,134,163,47,176,51,31,190,87,212,8,169,240,187,27,250,213,138,230,222,67,152,55,60,90,167,209,184,20,34,191,51,97,191,215,127,158,8,26,19,158,146,191,136,33,222,1,19,135,100,135,120,209,137,189,253,66,11,62,78,153,168,86,38,170,105,201,65,86,56,37,78,30,216,151,115,80,113,231,52,181,232,26,165,142,22,248,37,158,173,194,246,107,217,128,225,80,54,227,58,175,83,243,126,92,103,242,211,146,215,245,253,39,229,5,188,62,240,80,157,12,75,124,6,181,49,221,181,144,108,136,145,115,188,239,98,85,219,110,10,84,106,149,191,113,6,53,91,125,48,21,134,14,33,180,69,178,187,133,64,175,96,134,9,160,175,251,73,210,181,34,80,130,171,27,193,160,110,172,247,39,39,112,199,192,49,86,202,240,191,226,45,229,79,2,16,136,108,192,218,132,89,21,47,230,23,21,25,166,180,222,102,97,113,129,27,146,50,79,47,211,241,36,169,223,249,158,91,239,65,160,118,148,230,165,230,1,90,74,32,228,123,84,95,35,221,199,38,7,247,167,41,122,47,124,180,103,93,47,183,66,169,19,215,88,148,82,190,71,154,51,36,119,50,240,86,222,27,63,16,252,248,190,229,178,105,242,251,155,204,65,58,19,172,157,244,30,46,10,207,59,163,222,30,237,130,148,198,142,161,96,245,189,199,201,54,141,8,91,175,211,234,9,61,252,104,30,96,215,102,69,168,195,75,176,26,47,151,165,46,233,43,115,191,239,83,48,39,100,252,212,172,162,73,194,177,13,162,139,80,251,15,3,101,25,24,130,186,187,119,32,141,40,252,129,229,36,201,59,144,185,69,247,77,108,99,46,246,219,133,149,60,111,127,234,190,74,211,60,184,107,128,142,174,11,102,108,249,235,125,21,242,76,151,67,58,134,70,236,5,210,14,124,106,80,147,240,144,47,221,123,107,170,13,146,251,146,218,162,42,31,15,245,82,93,106,20,5,79,109,180,159,51,81,246,148,139,141,36,109,129,186,237,237,156,85,15,249,252,92,95,172,67,166,122,25,122,32,249,22,154,144,208,22,27,253,162,168,148,162,239,222,177,84,48,222,50,144,145,208,41,212,151,11,236,113,175,73,246,240,117,247,205,165,209,4,18,246,125,168,249,57,244,216,227,242,70,219,3,161,101,156,182,225,232,4,192,0,20,216,97,190,22,40,253,81,22,27,115,227,205,198,228,120,99,242,141,250,132,3,2,95,250,90,162,30,213,148,102,134,172,253,106,203,242,63,195,65,124,189,231,202,82,101,91,245,242,59,103,85,60,78,163,180,105,64,39,203,87,115,135,109,181,72,1,190,200,92,210,214,94,185,226,222,103,10,8,214,208,252,190,206,64,109,191,120,17,124,229,111,236,67,161,35,14,79,2,156,91,194,39,96,100,42,223,156,148,158,249,74,125,75,90,68,36,154,138,85,53,119,193,180,196,88,63,186,254,158,93,50,122,59,223,235,213,70,81,105,133,154,251,144,209,159,153,118,150,240,196,231,144,164,91,187,1,37,152,249,92,229,71,30,39,159,213,148,85,172,101,143,99,7,200,136,191,140,158,86,231,2,89,192,101,132,110,224,118,117,74,191,88,115,205,31,233,134,86,202,131,46,254,0,37,251,89,213,196,58,232,188,15,29,218,5,29,3,231,93,79,92,165,35,67,59,4,52,134,22,144,118,191,143,216,28,71,81,20,7,120,115,36,32,131,195,104,34,58,112,41,248,240,80,43,122,251,192,159,136,20,125,53,227,77,28,210,160,41,154,246,109,18,31,44,52,143,109,251,106,188,97,228,50,86,218,170,9,185,28,97,176,123,207,39,118,147,87,23,253,203,161,121,31,127,182,206,201,84,59,204,39,77,216,161,28,190,95,215,163,20,43,197,76,254,98,108,104,5,54,114,106,84,65,160,178,70,86,250,171,97,242,143,201,187,117,43,109,232,21,112,102,176,37,1,100,135,223,190,207,157,93,71,127,28,118,59,229,63,15,30,23,119,243,239,221,48,153,203,147,243,152,223,236,111,176,20,178,126,224,90,133,104,154,191,37,162,189,25,111,248,147,238,225,162,128,67,246,85,254,111,106,105,142,212,163,174,104,176,100,6,190,14,186,203,126,107,232,201,106,129,196,187,148,80,63,113,221,236,70,231,217,243,207,75,93,36,229,115,54,28,21,250,47,158,239,157,17,95,229,238,39,190,0,121,142,47,206,242,61,107,179,235,123,196,91,21,157,38,178,75,139,170,122,147,192,243,244,162,30,74,139,234,82,23,251,18,62,63,178,121,180,41,239,62,149,200,157,22,185,131,94,222,165,188,112,27,108,53,195,10,255,192,212,69,19,181,114,246,252,253,184,71,179,19,178,60,173,148,189,185,227,52,246,162,187,203,72,24,71,8,195,208,158,104,213,217,86,229,17,119,185,45,250,194,150,247,7,226,10,40,228,150,115,210,179,119,144,78,228,35,121,252,181,73,23,57,196,91,226,32,72,40,177,180,112,86,122,222,214,141,205,68,232,102,253,230,136,74,211,196,213,213,250,162,243,138,18,228,221,249,57,51,252,116,52,140,239,195,197,166,210,105,153,81,227,196,163,129,52,203,187,216,132,213,1,124,74,132,84,253,123,195,239,102,193,139,124,59,18,86,124,219,97,39,101,142,5,67,150,102,56,209,16,43,163,250,77,54,61,124,199,6,66,10,129,185,157,72,38,133,230,81,200,204,218,25,52,25,198,186,44,203,166,59,26,9,75,139,240,127,3,226,156,166,67,191,80,98,158,26,60,29,218,24,154,219,70,255,250,41,134,177,46,124,60,100,206,192,143,189,229,35,85,117,163,114,136,139,217,36,120,249,150,127,62,183,93,241,198,243,13,48,215,134,96,179,157,28,10,88,10,89,15,241,172,66,52,89,12,201,104,63,223,24,194,129,228,189,162,224,132,87,254,71,105,186,101,173,132,157,212,66,26,243,138,139,0,204,4,152,148,19,78,158,0,114,60,89,103,204,127,139,12,161,20,213,197,47,254,88,85,255,69,194,82,64,105,193,3,38,226,79,50,24,70,237,107,102,184,89,49,95,186,150,27,116,44,92,238,61,169,5,76,209,236,128,254,116,155,238,102,26,148,158,187,204,53,121,126,30,240,88,214,146,56,174,43,12,39,170,19,15,173,149,70,131,208,235,228,53,102,71,31,141,113,29,120,165,65,212,230,137,9,19,188,146,160,121,191,179,92,71,38,174,185,159,217,76,123,205,64,212,215,201,147,128,19,84,143,67,211,177,123,77,30,157,202,55,134,190,94,243,190,221,180,13,240,148,244,213,22,239,52,245,206,36,3,44,88,235,19,80,53,176,250,96,248,87,140,56,74,155,226,204,109,255,202,27,254,243,113,86,138,135,88,83,140,136,201,153,106,237,190,148,253,105,17,89,242,145,75,146,148,8,210,58,87,54,111,238,180,75,36,248,234,129,42,76,244,249,158,227,241,152,96,137,46,196,175,198,174,231,157,35,103,95,18,15,143,185,236,138,216,201,60,208,76,165,21,164,211,205,142,18,210,59,240,67,126,38,242,222,146,68,29,246,161,127,138,85,253,120,213,151,20,112,249,76,248,108,152,105,78,166,246,221,244,167,156,126,244,201,233,208,148,37,212,57,62,35,234,128,195,117,115,108,124,65,239,188,1,172,188,249,141,19,28,187,182,109,88,13,49,116,107,174,69,123,150,53,217,25,73,30,72,185,237,43,131,236,45,155,225,7,37,6,106,67,5,84,93,99,254,148,198,223,5,32,224,13,158,249,140,64,182,238,208,240,92,239,202,51,244,69,219,57,89,215,64,160,132,71,43,64,98,0,178,49,148,152,133,234,74,196,160,242,166,7,55,189,21,211,112,124,211,68,122,171,240,100,142,229,67,160,91,195,91,118,99,197,154,235,162,183,54,250,85,24,110,152,12,203,195,56,217,130,135,101,17,49,183,66,164,181,120,154,207,108,164,213,238,24,236,214,105,177,122,151,187,42,10,147,205,94,144,159,112,201,245,100,146,237,100,66,182,10,198,44,0,252,173,167,190,54,245,190,16,128,126,104,4,102,174,106,144,39,157,78,111,20,34,55,32,220,48,68,209,216,165,20,109,197,21,224,38,66,40,231,247,201,66,67,242,3,132,246,137,231,54,15,4,93,34,130,154,54,92,232,197,77,112,26,165,168,248,90,51,81,138,66,150,225,206,205,51,132,2,239,6,14,123,30,234,234,163,101,229,119,19,106,161,179,251,117,91,169,117,4,79,135,204,167,47,38,167,150,26,24,246,95,26,213,13,95,17,82,232,81,176,123,76,123,116,184,121,32,245,57,30,42,54,60,133,207,66,140,150,235,35,128,204,217,43,33,93,179,13,174,212,141,155,249,232,129,102,165,189,50,215,29,27,239,46,184,244,59,40,178,12,82,135,17,236,249,131,58,214,241,156,128,246,151,190,180,97,4,80,195,1,140,196,33,168,212,185,208,121,145,193,75,66,174,44,224,221,249,242,108,111,200,183,189,210,8,81,12,154,229,79,126,124,122,89,6,134,181,156,71,15,145,118,53,122,117,8,192,143,130,201,47,140,94,113,86,249,81,185,255,14,111,175,253,216,58,245,123,184,252,158,96,211,163,105,94,158,203,82,180,107,217,214,218,198,15,252,75,79,233,181,13,48,226,177,99,155,88,133,81,249,246,166,174,211,178,106,173,61,220,168,209,130,208,66,80,106,45,248,112,204,235,148,210,184,77,25,216,116,130,72,9,239,218,61,117,74,75,105,133,146,156,138,108,160,106,139,55,128,106,145,244,42,37,41,164,183,195,236,30,98,132,61,93,16,97,102,27,103,252,107,148,46,172,55,170,235,27,7,180,108,47,163,112,195,100,238,1,216,75,196,94,200,226,228,201,3,110,111,96,205,179,202,16,214,218,230,175,60,94,128,254,10,64,122,100,118,9,75,205,189,92,210,136,188,243,217,165,6,35,195,81,10,227,44,242,253,186,89,195,247,63,235,14,236,131,41,161,247,94,88,31,160,155,30,6,29,201,243,112,125,222,138,43,211,219,239,27,245,42,207,119,116,56,61,241,22,217,127,24,138,179,95,63,13,125,92,85,188,1,156,188,59,231,207,71,67,209,182,210,97,209,41,22,97,144,179,14,37,61,95,139,228,169,238,121,9,123,52,112,199,196,80,117,139,237,44,126,239,143,203,96,53,20,222,157,191,210,80,73,161,115,241,104,18,22,105,146,97,32,54,97,84,247,129,134,171,200,114,168,197,109,164,3,218,30,149,193,244,210,64,86,202,79,53,76,193,247,192,3,166,28,201,178,24,241,112,81,140,90,208,69,0,39,83,214,19,190,51,92,159,219,188,33,159,12,120,181,222,187,227,190,194,218,43,125,154,113,80,237,50,136,188,112,27,130,154,168,172,80,170,74,174,42,109,16,205,164,160,139,200,250,236,89,162,101,191,243,102,80,55,179,101,162,30,72,156,238,66,103,243,206,208,155,72,119,189,182,71,253,11,207,247,55,255,68,51,239,11,23,65,162,16,119,16,221,84,25,208,243,226,55,254,87,48,158,163,243,117,181,154,194,102,236,249,156,53,243,162,153,155,47,66,227,238,4,49,43,251,36,124,185,13,20,9,122,77,20,162,57,144,25,255,17,6,160,128,11,83,0,247,213,196,233,240,200,109,138,98,192,224,16,239,251,146,49,102,243,18,15,63,90,160,42,75,211,249,37,96,251,74,67,114,177,81,93,82,106,27,46,147,248,165,203,20,116,82,135,239,63,77,177,222,107,189,30,2,10,53,137,85,9,91,123,131,176,192,139,6,26,250,240,20,222,27,135,21,59,130,36,240,148,62,170,26,75,39,210,121,47,150,26,184,165,128,57,185,124,215,85,239,218,243,185,21,212,155,181,91,116,31,234,212,218,116,168,124,244,250,8,206,87,207,216,195,65,95,122,115,145,156,43,238,140,187,203,20,193,84,254,152,94,151,0,190,104,144,159,45,57,106,147,156,175,243,48,130,241,92,221,16,189,253,198,73,31,105,232,108,131,179,55,83,221,213,159,201,239,54,55,54,186,135,40,243,157,44,173,67,226,73,108,245,187,228,248,208,1,79,188,23,172,192,205,112,194,67,125,109,46,38,136,246,108,205,222,222,106,37,44,35,38,50,91,180,165,100,6,198,198,123,241,45,227,4,21,171,44,140,184,170,141,208,195,252,237,106,53,249,171,173,103,149,19,214,56,230,119,53,187,99,215,94,80,161,74,118,234,109,39,206,252,21,116,92,71,178,215,6,65,72,230,74,169,89,114,177,117,149,167,26,94,176,146,166,215,58,129,214,23,65,239,250,69,225,19,68,96,11,24,178,182,143,15,254,56,228,83,127,234,165,165,144,225,27,125,184,163,76,104,227,242,36,232,68,224,82,126,245,160,213,61,193,45,24,122,5,204,90,130,186,44,142,171,238,197,124,135,69,160,207,214,128,39,100,73,10,116,183,194,238,152,78,59,193,113,223,63,205,124,37,136,108,250,59,243,58,236,14,132,120,249,113,182,86,185,155,130,12,22,71,242,29,157,203,197,149,186,244,91,105,32,33,34,76,211,24,184,66,246,98,211,174,8,40,251,193,24,89,30,29,133,132,71,249,70,9,111,85,86,182,94,94,204,151,182,41,26,117,50,87,2,91,36,107,184,1,203,75,111,174,234,187,135,9,81,170,135,166,64,183,224,132,174,241,89,45,201,104,249,76,97,115,43,140,83,232,31,68,165,219,130,247,55,37,211,214,75,160,164,95,14,242,120,123,246,238,20,134,56,122,173,239,209,236,125,65,75,189,217,7,123,246,237,155,71,19,205,223,148,59,222,128,95,179,128,156,207,156,132,209,227,73,17,194,110,87,18,168,193,22,151,30,222,72,95,225,114,218,106,232,23,206,196,153,185,36,163,170,241,190,164,215,27,165,82,118,23,5,252,58,163,249,7,110,179,176,16,194,29,187,133,62,222,233,156,153,250,9,128,82,101,102,51,252,181,17,197,87,113,247,61,157,170,249,4,254,189,180,18,195,250,223,215,101,30,52,118,172,216,17,188,51,11,206,58,221,158,119,172,157,65,203,159,47,80,245,205,228,125,78,145,60,37,128,79,26,33,70,102,35,174,96,168,36,16,68,242,192,214,74,151,33,205,208,99,85,100,196,242,244,70,243,85,147,152,194,119,206,147,135,141,225,177,253,32,83,18,249,210,45,249,74,192,253,123,130,165,247,227,135,130,146,52,160,224,13,230,85,136,230,154,33,53,109,202,109,166,39,46,232,74,10,184,80,35,17,159,148,96,91,137,133,174,245,116,121,237,54,190,109,37,73,32,0,9,109,144,218,156,151,159,233,221,53,194,93,227,98,28,116,54,246,210,104,243,245,138,23,15,118,73,114,66,24,197,242,149,61,244,155,160,20,20,33,94,15,79,5,35,153,30,164,26,179,101,156,169,55,30,196,164,165,247,184,8,66,106,224,14,232,72,53,169,149,140,41,16,223,134,209,221,187,157,78,47,225,71,140,151,100,223,191,238,160,23,231,107,167,63,234,26,169,119,173,83,123,79,226,12,181,5,228,72,237,43,192,119,70,42,99,79,11,182,2,207,130,255,88,213,22,110,121,25,204,53,32,93,55,135,123,58,163,64,237,15,168,220,113,69,179,100,189,228,163,39,210,186,69,179,223,224,238,28,204,52,55,210,10,91,59,211,80,80,139,150,49,156,187,85,32,29,11,103,237,146,144,93,68,205,233,5,53,51,210,71,151,142,87,78,237,128,2,244,158,251,229,74,82,124,72,193,28,54,226,120,243,70,4,155,158,196,223,35,202,81,117,253,206,173,248,95,13,235,53,28,184,166,159,41,202,96,113,124,190,243,138,208,249,31,201,76,59,92,237,147,192,196,253,2,99,183,241,106,234,48,43,166,101,67,246,86,151,135,224,223,188,42,73,173,0,26,152,96,246,21,53,90,146,215,69,192,247,69,184,203,115,98,247,58,8,233,142,246,79,93,101,76,172,154,185,43,232,135,145,14,105,56,243,72,149,10,122,141,179,198,103,235,225,167,95,192,165,111,20,175,121,173,46,14,41,148,31,1,84,151,39,8,88,237,13,17,228,147,19,51,197,188,205,254,163,14,229,27,223,64,246,160,150,195,143,203,8,207,227,80,90,223,116,90,231,85,254,129,125,4,26,14,3,91,241,74,129,34,201,39,202,142,64,62,251,182,194,22,187,217,220,251,87,186,58,240,141,60,227,131,62,129,81,222,104,191,127,82,10,16,189,196,70,100,128,165,244,255,71,243,186,233,181,195,117,21,187,152,255,190,92,57,14,214,111,83,9,210,33,68,38,17,217,176,180,45,155,212,48,188,77,10,184,87,63,148,241,53,235,219,18,3,53,235,162,83,18,217,29,233,98,246,194,187,20,235,142,145,13,12,76,189,78,242,202,53,162,100,202,11,206,59,7,35,197,181,200,190,60,104,141,206,56,133,133,255,193,246,43,206,221,46,88,253,79,188,154,15,168,243,121,183,64,223,221,140,174,217,45,18,156,25,75,233,247,33,37,250,149,63,172,108,237,2,33,8,68,109,65,46,111,235,166,245,246,222,65,56,84,202,74,215,16,85,185,105,179,201,214,181,12,127,14,68,207,233,142,161,31,84,33,76,228,93,46,147,88,222,86,73,32,111,160,27,11,99,33,198,151,235,49,253,141,73,28,229,232,163,89,70,93,78,211,152,181,19,112,195,100,130,137,135,63,57,145,57,51,124,160,184,249,111,239,208,59,123,2,31,28,234,178,71,216,134,228,150,238,140,175,48,98,180,205,27,6,205,99,183,123,74,3,251,150,187,62,43,53,232,189,139,1,240,145,95,218,146,46,197,154,87,23,104,172,181,116,41,197,145,247,50,198,209,105,113,87,163,194,149,129,182,160,139,50,208,148,109,245,125,31,97,2,178,33,106,17,187,242,154,189,25,177,178,196,94,16,53,173,136,227,194,46,77,142,218,15,164,246,180,101,203,49,109,63,113,196,218,180,115,195,250,48,170,232,48,227,235,253,22,23,126,245,135,150,225,41,174,249,205,200,230,139,245,196,161,188,220,183,58,200,3,255,30,32,85,73,15,40,53,199,239,31,111,147,193,208,63,56,47,44,49,173,186,25,167,76,124,77,212,254,142,254,183,38,142,147,45,176,126,195,70,155,119,19,158,234,15,187,27,212,120,122,20,205,37,80,73,81,194,207,224,61,66,252,59,173,76,245,202,247,213,217,149,165,112,220,115,153,209,194,247,87,14,203,178,165,45,200,42,84,89,207,150,115,48,89,15,157,91,165,19,8,84,233,62,22,216,9,217,152,156,2,221,151,183,176,20,13,226,36,68,156,101,224,253,243,137,189,16,203,131,13,200,12,229,175,170,131,225,95,210,71,67,176,114,40,186,29,20,124,68,96,18,31,97,207,70,249,8,240,91,123,22,22,223,149,97,134,224,44,5,221,25,62,24,104,165,14,189,2,154,212,121,60,221,123,7,125,11,22,254,137,32,213,128,254,63,221,123,172,74,232,207,229,187,208,23,229,62,55,219,207,130,41,253,173,171,20,4,78,250,184,70,130,1,40,48,190,206,172,135,29,35,217,55,133,249,174,120,192,178,189,59,21,29,31,117,192,221,151,186,82,141,75,33,248,110,9,41,81,162,29,89,95,122,245,56,230,124,251,196,223,186,238,69,252,214,236,127,7,218,8,183,178,56,4,173,30,215,33,6,168,169,196,231,178,25,39,242,174,58,160,77,200,140,247,219,211,58,181,245,131,58,165,111,34,206,180,236,153,148,104,237,148,213,82,108,124,175,30,132,89,108,69,43,239,13,121,3,196,51,174,128,247,6,164,63,129,248,222,55,198,57,103,83,188,83,129,254,31,59,238,241,45,169,50,82,82,52,252,43,162,164,144,133,184,108,212,10,250,155,98,18,253,9,228,200,188,173,63,24,223,252,109,163,34,253,150,104,165,220,180,154,212,92,182,83,136,18,176,104,126,41,63,117,28,92,222,183,153,192,76,0,202,164,255,205,47,201,56,111,166,205,204,213,251,92,135,153,202,175,149,61,129,80,86,81,9,124,2,81,124,228,169,13,142,92,3,25,111,242,193,15,45,151,189,159,219,49,84,201,253,14,43,56,75,106,200,117,23,117,35,62,133,198,81,218,49,93,228,6,164,208,157,39,245,124,146,138,3,9,37,123,195,219,156,159,254,195,76,24,101,46,57,197,234,153,196,241,201,175,89,95,140,6,82,241,105,246,245,195,10,96,253,41,82,249,92,175,45,174,121,147,51,51,24,22,85,236,180,172,183,83,71,187,151,42,221,124,106,48,200,138,124,202,67,25,133,198,138,31,147,145,229,90,235,96,203,21,120,156,10,101,38,154,243,73,169,244,115,4,60,61,200,238,136,162,231,197,12,92,210,86,127,96,41,125,245,10,234,66,6,174,6,157,130,158,63,16,57,160,209,187,148,175,88,85,38,62,142,22,80,191,21,143,76,151,233,86,142,65,223,138,163,212,104,24,123,15,193,102,53,10,53,1,196,1,207,25,178,40,229,190,56,179,124,160,185,13,185,96,25,201,42,71,228,157,33,125,10,174,204,138,233,195,207,116,251,21,133,31,43,88,169,125,143,119,212,8,240,92,31,143,79,234,219,247,182,79,157,172,18,168,121,206,227,182,139,174,63,125,64,166,148,49,55,228,55,174,97,243,11,183,28,51,250,162,24,233,9,12,63,35,206,96,159,193,157,141,184,50,218,23,116,120,58,91,124,140,147,32,118,210,61,11,25,157,140,189,113,55,74,140,94,152,215,92,98,145,216,207,91,53,193,41,158,128,227,141,131,61,86,205,44,220,48,153,14,192,48,65,118,68,35,179,56,253,205,254,72,49,252,236,17,245,81,233,137,6,61,27,233,193,185,122,239,145,181,225,227,86,59,103,188,249,60,146,48,199,71,158,23,233,115,209,5,33,95,178,78,249,28,255,24,67,240,231,142,185,151,215,69,185,185,58,228,94,208,135,48,37,204,196,37,64,124,162,73,102,124,133,86,226,54,91,104,144,112,156,177,46,98,28,53,134,62,139,68,56,137,97,93,42,198,51,223,200,106,150,211,98,242,221,35,91,129,238,41,112,62,189,17,242,128,164,157,156,212,190,15,251,123,60,149,202,48,38,84,250,57,230,197,13,20,179,225,5,217,99,67,125,62,47,16,138,243,247,249,39,226,72,143,185,12,69,203,149,98,41,82,244,230,205,179,218,129,226,19,33,19,239,149,75,184,18,163,121,121,67,101,43,176,222,172,58,165,17,9,120,139,121,12,228,252,74,74,81,102,12,10,202,121,117,202,214,187,92,118,150,143,210,125,118,140,35,215,199,242,14,183,136,249,79,213,63,13,197,119,253,97,21,25,177,199,206,5,53,55,150,89,195,186,88,53,56,147,121,75,199,2,189,134,202,235,18,80,142,55,234,193,205,105,182,241,57,110,157,9,54,209,190,180,4,78,238,75,42,47,42,227,234,163,247,87,90,92,43,69,196,75,157,233,95,179,78,133,84,177,200,3,95,123,105,198,132,122,226,182,186,4,8,157,13,3,151,84,149,51,108,94,73,181,233,1,9,21,76,112,95,32,87,25,80,118,74,118,76,118,252,54,224,109,240,23,86,240,48,215,109,93,83,195,184,104,42,6,92,180,39,203,126,123,99,140,143,254,160,141,213,141,3,70,109,186,107,7,98,165,15,212,100,49,162,165,77,187,1,57,30,146,69,23,9,218,104,169,35,2,160,82,6,223,188,16,233,206,207,164,40,137,158,210,149,222,171,225,41,120,130,187,151,150,140,192,142,135,103,233,160,187,60,49,147,245,7,57,197,139,108,39,92,134,210,93,247,200,184,141,83,102,26,170,80,173,8,156,96,82,79,90,175,113,34,15,7,110,18,180,149,178,29,173,157,104,123,43,208,99,28,229,31,168,61,76,52,61,73,163,238,32,178,13,30,113,56,83,64,17,91,47,63,109,186,13,54,3,192,226,230,3,30,7,185,165,201,155,146,89,134,9,147,66,189,225,115,129,93,144,162,4,163,230,8,214,31,194,236,136,22,73,113,209,155,151,120,203,42,227,91,17,171,84,168,244,13,127,90,141,119,63,87,122,250,180,119,234,68,239,171,75,154,194,139,150,81,196,231,12,248,239,197,9,151,145,216,118,130,115,99,43,83,177,139,211,105,25,237,57,151,208,96,134,224,73,34,240,110,33,42,43,2,118,113,16,214,1,163,142,157,1,242,139,226,215,132,89,61,182,163,223,55,197,113,14,149,186,26,71,167,71,154,78,167,29,179,105,77,220,38,110,78,204,75,233,213,149,198,146,229,42,206,219,36,33,170,173,49,4,147,99,196,100,28,22,194,181,10,209,28,173,83,23,127,126,251,100,244,139,130,220,89,124,209,34,155,151,66,26,167,2,99,3,40,99,13,121,117,124,21,124,11,222,84,252,9,237,80,71,38,21,252,95,157,209,202,61,135,159,229,245,49,34,122,87,140,120,191,116,50,196,90,34,113,123,92,11,253,142,44,239,202,238,104,194,79,50,151,125,153,174,240,203,11,208,123,224,75,249,20,237,55,119,200,95,223,246,170,217,217,100,24,194,43,104,146,46,111,229,231,166,248,3,16,136,230,21,210,8,0,6,160,128,25,51,149,65,251,153,174,124,215,205,224,222,114,119,220,175,27,103,118,201,133,26,17,26,104,183,200,73,98,254,35,86,18,76,159,36,65,210,184,145,146,167,99,175,218,98,223,135,240,67,15,26,180,194,2,16,39,99,116,144,81,1,215,246,14,107,143,10,118,133,211,208,101,125,4,82,235,177,136,168,208,23,43,6,27,240,46,239,174,198,54,24,254,10,21,148,236,124,22,172,75,247,143,43,197,162,139,142,24,149,91,140,200,249,111,57,174,16,163,191,73,83,58,110,152,204,40,3,125,160,230,104,189,142,248,139,91,140,100,94,92,25,41,159,174,43,205,128,163,222,62,98,79,47,252,116,158,34,81,234,99,65,32,95,144,188,113,23,92,144,119,185,115,18,108,117,113,84,254,84,49,216,85,125,224,189,17,107,204,227,165,252,128,238,147,67,181,23,187,2,210,211,9,62,70,167,18,204,198,0,112,53,232,32,126,68,182,73,177,220,254,239,238,144,124,140,96,117,20,187,249,13,123,188,246,62,25,235,55,181,246,85,114,183,12,44,0,129,224,188,102,43,106,129,254,4,114,106,43,226,91,236,55,121,223,45,192,159,154,54,46,211,102,125,247,205,218,46,211,171,160,124,125,153,76,255,16,26,196,229,138,31,93,15,99,197,129,203,165,72,136,236,203,157,26,134,11,95,103,226,251,193,161,74,153,5,129,79,148,168,66,4,251,43,249,223,58,23,65,230,238,134,92,40,23,107,193,229,189,53,209,197,184,151,159,215,18,106,254,73,108,162,168,54,7,58,104,66,71,247,109,45,160,228,255,91,64,106,251,75,112,47,39,38,163,102,33,150,25,113,209,24,103,238,202,195,27,227,217,99,190,137,224,108,25,149,107,83,125,98,39,148,199,192,129,83,36,180,93,183,18,3,165,57,88,167,146,60,58,1,97,86,106,177,177,252,17,81,248,12,74,192,124,122,55,54,191,67,152,8,28,41,222,140,122,19,188,77,14,174,134,206,41,143,161,57,84,81,117,155,125,152,252,102,137,183,156,230,163,12,63,234,115,178,246,231,191,91,34,194,162,137,66,32,191,225,145,61,198,100,212,4,92,255,122,88,95,86,224,237,37,76,91,44,171,98,19,147,224,156,207,157,12,187,173,79,87,30,164,241,109,211,167,135,48,82,121,89,205,101,155,132,206,216,104,144,7,215,253,10,77,137,99,78,188,124,110,238,33,131,223,53,115,124,154,41,121,76,207,18,97,42,27,101,233,53,206,139,178,195,47,220,51,206,61,219,200,104,75,41,64,43,6,138,26,31,135,38,125,84,122,255,143,61,112,15,39,222,142,203,124,121,214,16,234,248,89,14,227,102,135,104,158,55,36,36,20,104,155,18,7,176,202,103,185,126,22,123,65,91,112,91,75,238,98,97,180,100,144,42,165,104,186,92,209,225,20,118,220,121,178,172,175,61,101,111,85,142,55,26,203,150,237,64,154,249,78,76,84,99,112,90,230,169,124,155,214,68,198,186,80,57,54,89,8,115,251,165,2,227,196,198,73,72,50,231,182,22,146,89,125,67,97,142,13,245,75,126,79,3,201,27,78,139,27,185,201,8,87,68,49,203,107,86,4,229,158,63,71,222,252,138,25,230,43,138,2,33,161,49,120,24,79,168,245,141,141,134,147,101,46,79,220,87,40,246,194,253,113,181,57,48,6,254,203,68,220,152,132,175,198,249,196,134,55,239,144,39,82,181,85,74,54,101,91,115,107,15,61,109,213,167,86,213,39,228,36,50,69,138,92,230,98,5,189,160,92,44,172,51,167,178,48,243,216,85,100,191,255,11,104,250,214,115,209,112,72,229,110,216,54,27,254,209,121,205,34,119,180,61,46,122,28,213,164,81,136,166,165,191,148,159,14,114,120,134,186,69,190,217,135,135,73,158,62,52,117,246,233,183,94,251,81,38,119,195,81,22,128,1,176,122,136,101,70,108,243,48,233,25,206,141,252,84,121,37,150,85,83,182,215,248,222,147,35,230,131,78,220,243,6,194,80,144,144,102,144,117,119,180,232,212,134,33,23,3,14,88,96,159,254,231,248,57,63,55,238,101,185,228,155,193,14,190,196,213,26,134,144,223,129,119,66,20,145,115,207,188,167,159,174,54,34,180,144,203,16,131,23,54,202,215,137,34,65,132,148,9,174,134,10,98,96,103,254,20,201,114,187,65,118,106,254,166,98,64,109,7,218,108,223,155,219,186,15,173,254,32,184,153,175,163,232,163,127,98,148,237,127,61,207,239,118,218,218,142,85,114,152,233,179,82,205,166,80,39,156,187,186,219,114,39,119,253,122,87,85,2,249,40,4,35,54,151,13,100,180,177,234,194,187,8,150,184,34,151,12,169,114,158,11,126,76,142,81,60,198,89,170,248,220,187,148,185,141,195,128,169,162,90,14,0,91,2,104,134,229,172,68,153,31,85,67,199,148,166,116,166,202,198,208,79,141,29,251,32,155,177,10,123,210,150,165,192,127,122,19,196,205,71,173,26,81,111,123,223,173,222,180,210,159,98,253,206,253,208,116,255,49,199,205,211,89,224,62,9,239,251,26,120,35,180,51,165,143,89,42,55,40,232,253,130,21,248,245,69,153,106,30,7,26,238,226,203,46,75,153,228,46,133,229,169,210,153,227,1,11,23,12,221,148,108,226,179,82,144,205,76,50,212,32,54,87,230,25,90,6,21,65,14,187,217,101,194,193,54,92,83,5,200,47,87,49,87,64,120,143,95,34,200,46,144,167,105,138,245,54,169,246,226,145,174,128,40,7,251,42,186,255,86,13,209,184,239,217,183,56,237,133,240,199,99,112,195,100,88,72,134,9,178,159,183,136,139,11,255,147,171,52,137,246,88,117,220,78,148,221,193,197,36,44,171,211,226,218,162,163,236,75,68,23,207,238,111,63,183,18,209,254,170,23,101,181,149,75,216,109,105,247,147,68,80,164,41,129,61,201,124,204,178,82,35,33,174,186,232,180,123,200,209,217,195,122,218,35,161,247,156,111,156,23,53,82,215,100,175,188,35,155,235,84,204,240,58,127,6,114,5,67,125,2,217,217,46,220,89,138,191,77,6,33,50,214,52,117,106,9,152,255,192,223,241,173,35,81,93,59,18,213,228,51,229,91,195,125,198,42,202,90,90,5,165,250,213,53,25,184,241,147,4,134,164,234,181,112,247,75,139,37,70,104,113,172,81,110,179,50,65,8,19,190,156,150,242,228,197,119,221,239,233,125,249,141,200,20,80,220,231,234,92,207,123,94,249,61,61,65,57,80,168,208,12,38,240,170,254,37,114,245,25,199,242,65,201,152,126,121,112,28,78,250,245,19,25,38,130,18,190,140,108,81,245,49,10,139,220,192,0,70,82,220,79,255,198,31,237,95,83,3,255,70,121,156,204,229,201,249,3,146,199,114,88,10,89,57,184,221,244,218,90,73,242,56,55,234,231,229,249,88,62,203,68,45,189,153,132,32,253,141,103,47,229,41,172,10,172,67,65,6,182,89,102,121,80,170,209,8,42,190,230,124,142,189,198,71,116,91,5,81,231,70,147,189,93,153,197,90,90,128,90,66,196,130,74,76,219,68,243,133,121,179,244,108,27,201,201,119,109,232,69,37,109,86,112,1,178,16,253,202,31,209,243,155,187,198,46,205,249,31,30,38,154,120,75,89,61,92,174,235,113,199,204,23,21,140,244,152,95,228,100,176,179,159,215,63,20,127,112,99,180,102,185,159,144,121,211,212,7,246,124,214,120,165,171,217,214,56,11,216,34,235,66,122,62,79,99,89,211,237,232,91,39,98,63,114,252,54,59,12,7,148,30,52,50,194,74,36,159,146,38,2,237,92,82,250,187,37,191,223,55,124,132,149,231,200,108,169,135,85,228,119,164,11,143,244,203,65,145,11,172,200,244,64,136,159,233,235,29,233,221,210,120,42,128,127,216,106,29,55,182,107,244,187,42,166,91,209,205,186,228,254,33,88,206,53,169,96,198,237,166,31,99,230,249,252,224,150,174,230,227,93,236,164,107,59,183,46,61,94,176,220,30,214,92,241,210,112,104,243,95,193,166,10,114,10,209,240,97,98,183,23,203,57,173,18,147,196,92,110,148,55,228,96,180,58,123,230,154,101,156,184,231,253,116,251,244,80,94,238,177,204,41,73,240,69,49,50,251,192,195,72,11,237,178,198,88,194,127,1,150,89,35,226,13,143,148,32,215,121,86,103,205,116,219,179,90,172,27,100,49,7,48,222,48,252,159,19,127,79,44,98,70,91,112,195,100,20,31,134,37,9,114,30,15,127,208,188,237,197,148,239,96,89,249,44,130,196,57,36,172,47,240,204,37,207,172,8,222,165,43,175,0,32,125,205,151,185,210,144,11,100,33,236,92,138,212,250,13,222,79,59,174,30,163,124,203,253,167,27,6,187,78,225,98,26,67,233,92,192,47,138,123,253,68,249,87,29,16,194,86,238,192,107,16,178,34,224,161,231,80,68,105,58,104,105,222,142,26,178,83,163,15,241,75,152,125,145,102,55,160,4,255,187,55,120,239,125,140,188,48,7,179,103,34,252,113,181,5,174,17,122,181,56,215,244,214,233,9,49,53,171,88,153,8,159,148,253,233,148,174,206,12,203,253,210,185,114,233,127,128,110,126,192,179,210,113,65,209,255,155,148,244,174,1,135,138,152,68,24,118,150,221,98,120,130,234,96,3,99,75,170,1,47,95,190,105,211,54,57,88,248,174,227,135,133,150,49,148,63,195,137,12,196,196,40,231,37,154,41,28,201,5,206,130,17,220,117,111,193,247,123,252,231,31,243,28,102,210,174,128,128,24,17,145,55,27,228,134,119,152,162,231,236,220,104,69,202,142,73,246,92,6,59,27,191,153,79,156,235,246,116,128,73,51,150,247,238,171,250,9,169,132,1,125,202,131,51,58,233,9,211,242,222,163,34,34,253,165,30,14,189,144,58,217,80,126,84,175,228,217,165,28,187,37,192,41,49,22,248,96,244,61,16,92,144,171,103,195,211,193,255,131,206,218,87,146,0,180,163,141,100,198,102,45,117,121,116,93,25,66,35,226,65,60,157,173,135,123,140,170,160,27,19,68,227,189,167,217,48,109,237,252,53,115,179,9,236,0,118,48,138,39,184,151,13,147,81,179,7,75,232,188,254,83,89,76,140,218,141,247,36,225,253,109,156,89,53,57,157,68,255,109,156,101,82,251,206,137,254,162,5,255,230,85,33,23,179,62,204,174,8,165,124,243,118,219,51,69,48,148,193,255,229,199,100,127,235,57,76,82,165,216,237,238,32,153,113,94,148,21,205,123,33,205,34,164,167,174,236,129,241,134,51,23,174,49,152,227,128,237,113,250,179,49,180,92,141,230,118,93,242,52,249,113,104,83,15,168,175,191,221,232,70,79,22,131,109,241,152,28,116,89,195,194,245,79,126,99,7,163,22,132,117,24,174,195,236,233,29,113,252,34,246,213,127,4,132,208,128,169,186,194,65,58,175,109,115,248,104,116,236,108,20,249,35,89,182,244,132,140,233,228,23,77,209,61,6,218,92,19,75,157,20,116,140,95,114,181,41,188,103,194,78,152,148,235,242,179,25,176,241,124,148,158,63,167,126,246,82,127,238,43,1,202,63,54,168,200,8,145,235,235,201,20,129,157,56,19,54,3,185,2,170,177,194,229,80,66,99,142,21,106,212,19,83,137,106,212,223,253,78,148,138,103,127,0,126,88,69,214,66,157,215,76,31,233,211,133,100,232,25,18,41,165,115,173,190,255,192,179,50,101,177,101,142,109,39,31,79,121,92,146,42,129,203,21,125,37,255,107,203,156,33,194,92,80,177,119,21,62,151,119,242,222,46,37,68,162,8,194,220,110,180,199,123,78,101,247,18,248,142,77,11,125,223,132,225,146,228,199,167,21,149,30,163,5,197,15,232,17,36,249,192,207,140,78,160,223,57,187,161,207,177,193,211,74,42,240,128,231,133,200,229,59,219,107,218,247,235,154,120,45,70,230,202,95,27,43,96,93,201,120,161,149,204,13,153,33,120,40,50,48,81,50,75,26,66,171,203,183,172,138,244,228,167,163,90,105,218,34,210,189,119,151,232,203,143,210,248,15,182,196,116,172,117,220,46,165,85,174,43,234,189,43,33,12,22,207,60,165,4,87,114,104,120,73,20,131,126,51,126,244,205,151,124,75,186,118,93,53,156,127,203,62,219,200,80,66,58,194,122,32,87,220,105,118,39,87,147,246,145,212,225,198,92,31,49,154,179,77,4,235,114,213,35,20,117,6,184,223,72,71,196,105,60,206,92,250,179,206,99,96,118,204,21,246,21,209,254,70,9,198,248,150,39,182,149,47,105,211,144,119,124,244,17,118,92,122,208,236,11,155,49,127,127,31,31,2,93,228,242,16,107,64,77,220,107,64,154,138,104,53,232,20,212,3,236,49,154,7,123,112,78,32,117,87,136,22,152,157,42,255,64,234,148,191,33,167,190,86,247,157,92,112,156,188,75,124,250,54,126,165,140,220,140,248,185,174,50,53,160,192,14,243,42,68,211,220,8,72,155,241,183,52,240,196,44,43,155,181,34,146,62,202,121,235,121,242,82,120,39,175,67,20,146,220,44,207,162,69,96,113,148,102,152,118,18,154,123,252,62,83,234,110,124,59,161,232,83,242,190,202,35,134,136,231,3,66,49,157,50,41,230,95,146,82,96,237,39,24,79,112,126,71,157,255,180,31,45,242,123,129,63,182,70,16,41,115,164,11,15,28,255,105,249,187,98,244,87,33,122,79,226,114,180,168,33,186,122,123,108,84,172,49,46,247,195,221,51,110,215,100,197,42,39,218,26,234,239,165,14,36,4,74,212,223,179,51,5,95,49,62,6,87,138,152,209,86,106,45,40,90,233,244,187,64,250,218,215,14,63,33,76,61,68,135,2,108,247,215,63,36,85,55,161,180,90,146,62,115,73,115,65,208,149,125,134,227,144,171,240,151,15,56,150,53,88,237,94,94,163,213,39,208,39,232,150,67,60,246,142,116,167,134,200,195,216,17,100,23,139,121,84,245,7,244,248,69,238,86,52,244,184,78,211,0,64,28,208,203,146,69,41,247,197,219,254,131,217,95,122,249,21,175,223,211,53,252,45,120,242,3,188,111,126,104,230,138,208,213,137,231,89,69,119,70,139,111,195,52,158,114,108,77,173,154,84,123,131,235,222,212,230,155,183,120,61,202,12,146,24,218,242,71,122,177,37,32,122,214,182,24,91,238,121,141,123,36,168,139,8,9,146,160,150,66,246,72,217,83,220,63,56,142,177,247,161,32,176,215,85,66,0,74,32,255,170,141,139,25,117,253,104,112,37,148,230,55,41,84,127,159,78,163,71,222,128,65,221,156,13,121,201,143,203,72,29,61,41,66,201,56,253,35,192,9,115,217,155,114,45,153,47,120,28,30,166,101,191,176,207,246,28,186,128,252,191,149,8,246,173,219,46,69,10,146,92,119,126,183,168,230,244,112,222,206,182,254,207,37,43,131,205,80,141,117,155,25,149,140,7,102,8,221,206,153,134,102,33,232,227,175,205,77,198,247,72,19,77,244,222,119,176,248,189,174,117,48,15,213,160,176,203,87,79,49,86,86,165,248,232,101,82,180,212,31,200,193,46,219,23,37,238,240,237,72,181,199,88,254,190,186,240,29,207,6,210,76,210,124,125,254,215,92,250,237,119,134,62,109,135,66,166,91,215,76,35,4,180,161,23,197,215,41,59,2,81,8,195,148,31,249,163,107,194,254,218,225,196,132,253,117,185,85,30,218,190,240,190,124,124,31,95,183,0,90,253,117,138,143,107,161,18,101,138,2,147,226,122,86,203,252,238,84,91,104,99,182,213,106,220,2,31,233,105,213,254,91,9,51,217,130,146,219,146,226,255,150,204,125,102,250,64,205,251,77,155,226,230,127,147,198,44,150,133,36,116,216,161,206,165,97,222,25,109,231,67,65,11,107,124,47,79,244,228,243,152,134,142,62,84,250,237,222,88,207,202,110,20,9,155,94,87,204,30,98,220,109,198,242,221,58,145,207,92,143,18,208,33,5,118,210,80,171,233,252,174,44,249,9,105,79,92,13,31,115,158,79,114,112,187,56,19,137,11,51,184,135,241,235,85,64,144,118,59,200,194,88,129,68,22,238,20,220,48,3,52,80,30,9,252,17,106,80,39,105,171,138,36,226,171,243,89,240,75,0,197,106,120,119,68,43,84,243,61,28,40,11,14,245,52,31,248,103,22,64,5,110,101,228,246,118,141,71,99,52,203,204,251,249,79,136,182,59,160,82,242,178,60,96,254,65,131,29,205,112,109,241,16,59,149,112,121,167,210,131,173,123,129,90,188,148,17,152,177,183,37,223,255,173,172,105,146,56,217,130,105,163,119,25,89,127,201,22,53,102,159,78,105,165,4,208,107,16,117,94,166,161,191,247,233,149,73,144,211,91,47,246,103,179,181,182,166,202,26,52,14,150,16,231,228,104,170,25,182,45,53,202,208,149,163,105,105,73,30,88,118,98,74,192,37,20,231,229,208,115,22,75,178,223,47,234,245,15,70,244,57,163,235,158,238,123,174,116,120,88,24,243,95,76,247,94,180,29,62,213,32,26,253,234,172,13,126,79,254,55,67,177,114,130,51,211,143,240,19,51,12,130,83,20,132,30,150,148,95,222,111,213,84,208,210,21,37,247,140,203,127,134,117,213,243,2,197,114,217,139,244,211,235,60,185,104,11,53,153,22,163,10,247,154,225,227,146,154,172,244,94,89,147,140,60,94,189,61,89,255,143,101,245,233,154,181,126,74,82,195,249,251,249,14,78,204,79,18,193,245,233,211,100,194,246,188,165,237,242,38,173,186,166,39,212,226,89,73,25,110,203,122,105,94,8,61,91,216,55,123,118,125,147,247,135,250,18,211,15,218,84,133,206,22,129,224,122,179,36,248,91,80,120,213,148,142,183,71,2,29,48,237,52,193,161,213,137,133,213,231,40,35,218,108,37,156,194,108,145,250,136,64,158,161,199,70,33,240,211,54,14,233,81,44,118,135,81,53,116,211,101,97,104,12,157,154,139,240,116,158,41,150,142,180,194,104,81,19,114,92,194,71,27,142,124,83,75,255,165,191,128,90,226,21,201,97,139,4,120,30,130,204,157,160,134,201,90,31,86,223,175,68,229,0,244,188,98,58,115,50,231,37,42,72,197,254,253,42,196,1,172,74,50,216,217,172,110,191,62,212,253,253,18,137,30,151,235,245,143,25,7,111,226,202,0,7,223,222,68,94,163,141,206,196,114,238,225,44,211,137,122,23,3,9,139,101,118,9,248,152,188,253,123,116,38,95,55,159,144,1,176,245,125,91,185,221,212,145,232,254,10,76,56,132,186,165,34,102,174,180,106,181,140,156,204,188,62,73,214,240,209,115,217,215,28,92,145,69,201,68,240,34,40,77,196,5,252,92,103,12,53,134,54,166,119,243,148,15,24,249,184,54,52,42,184,209,42,83,245,219,230,50,154,145,75,66,4,234,22,108,63,247,102,163,181,50,224,56,105,57,240,71,2,29,57,139,62,163,50,13,165,192,87,141,50,30,225,203,195,248,100,173,160,188,13,190,226,48,193,8,175,201,110,205,213,195,91,6,244,31,235,191,249,142,232,48,214,118,205,216,44,147,70,243,59,145,5,169,54,58,15,31,245,148,37,22,106,19,42,187,63,135,45,40,251,44,146,88,169,169,153,42,235,123,138,140,218,193,154,236,13,15,249,133,194,53,105,66,174,134,107,133,22,23,129,167,81,66,235,99,46,125,113,223,131,62,168,49,191,138,126,175,173,96,161,251,104,191,232,153,238,11,129,135,116,26,161,154,40,93,228,223,46,235,134,0,67,80,208,234,208,96,31,172,254,126,210,76,149,254,253,195,12,198,126,214,214,239,57,151,124,84,246,115,117,98,171,92,29,37,145,22,196,174,85,15,166,103,83,211,14,239,255,178,155,40,254,38,104,65,26,93,14,224,35,38,236,178,99,244,203,45,16,105,93,85,248,87,188,200,96,61,144,196,160,12,122,128,120,50,12,248,11,19,138,0,15,50,32,39,244,20,53,237,182,71,59,106,119,186,125,42,90,163,249,61,228,170,236,23,72,90,250,178,128,223,109,162,39,84,15,189,48,191,194,237,60,73,202,120,15,61,90,215,38,248,188,51,133,15,165,240,24,177,198,197,16,171,174,68,199,65,94,156,50,71,22,65,247,133,52,150,224,79,66,116,148,114,124,148,205,66,122,108,75,2,165,225,56,47,106,161,117,12,149,195,155,165,65,42,44,112,10,234,129,204,199,65,133,136,165,4,109,91,184,127,70,229,188,238,103,79,173,181,202,43,49,130,246,16,194,117,212,2,73,102,40,204,121,59,158,80,83,139,152,35,99,151,83,156,91,220,135,6,221,230,76,228,145,105,206,109,216,167,85,75,23,59,145,250,74,206,255,139,215,240,88,127,2,57,120,108,181,205,195,107,215,139,96,41,7,192,190,120,28,134,39,29,218,103,89,159,77,85,121,138,170,15,206,44,117,130,191,55,52,244,118,198,80,89,229,103,240,13,198,72,56,127,173,118,24,143,120,28,231,159,218,34,202,13,51,117,198,10,114,38,150,176,6,241,78,175,173,241,19,132,191,125,70,200,109,194,94,12,216,188,183,152,31,176,158,125,149,32,194,18,243,81,79,148,230,120,17,178,237,110,252,107,160,16,235,229,134,124,148,153,146,15,115,240,206,102,223,230,145,23,235,215,101,34,129,235,180,180,73,180,160,203,12,166,167,118,83,67,57,99,143,124,160,136,176,226,75,133,134,245,13,149,252,16,153,112,100,95,5,135,165,50,231,203,76,211,98,105,120,145,103,109,130,159,204,243,229,110,134,45,117,252,53,24,111,139,193,109,115,255,63,87,249,57,94,55,125,213,121,74,145,2,224,230,52,102,93,46,222,189,141,118,116,175,65,34,127,150,218,209,142,192,155,48,10,91,168,70,51,101,178,242,91,164,90,138,208,204,96,170,87,216,248,135,174,180,57,237,76,185,178,46,209,34,173,183,105,253,37,212,84,159,90,99,253,196,117,121,66,64,235,39,139,147,238,41,49,153,5,44,121,234,240,254,144,184,116,17,197,171,217,245,254,64,116,17,104,51,28,122,77,41,239,5,173,106,228,245,192,238,233,57,56,204,184,184,240,231,90,125,161,142,124,196,99,104,98,59,105,223,90,141,95,56,228,102,32,29,200,174,32,189,143,67,122,116,209,115,14,73,165,75,214,18,114,74,230,21,83,102,2,36,101,238,76,26,132,48,226,20,2,255,13,10,83,106,152,2,184,123,172,162,230,127,89,225,183,231,139,209,132,105,123,153,202,144,90,78,71,191,222,76,240,229,147,116,37,129,73,205,90,252,73,252,202,0,214,40,90,179,124,141,20,227,207,172,49,239,51,4,215,119,140,245,107,177,125,78,242,123,139,76,190,103,63,235,218,216,50,155,125,32,216,144,199,74,182,124,244,84,150,16,56,238,125,89,242,126,61,138,126,253,233,66,2,78,90,194,76,223,6,23,189,70,76,244,246,95,168,6,245,64,190,113,131,201,91,106,30,170,12,13,8,82,69,137,22,91,49,36,102,122,251,210,26,42,44,54,251,183,66,30,156,199,79,17,93,66,28,238,78,209,167,215,18,97,185,31,204,140,176,2,165,31,98,231,80,81,139,125,173,37,164,214,54,189,123,245,33,18,113,69,246,63,128,237,241,18,83,0,183,249,49,157,98,196,117,36,157,48,28,34,56,203,76,132,135,9,26,183,22,40,107,172,87,18,61,168,169,243,55,250,44,76,102,203,28,221,37,76,126,203,186,173,143,225,77,228,185,224,116,182,247,192,109,103,151,6,72,220,37,7,163,165,112,243,3,112,81,28,86,219,84,84,219,217,117,185,160,164,72,62,17,122,217,248,158,227,184,82,58,39,174,208,8,105,247,177,227,17,39,40,251,103,140,34,8,105,196,253,123,101,23,27,172,15,237,123,46,175,171,253,103,40,33,235,203,198,176,144,156,233,251,124,185,86,44,81,138,125,21,136,185,231,253,236,175,15,220,253,57,230,248,124,200,180,62,120,66,21,203,71,217,100,55,107,227,198,208,148,211,205,42,222,92,82,34,152,48,214,237,123,166,128,22,173,32,104,64,93,217,109,17,250,159,43,1,183,155,94,251,29,3,228,47,141,149,192,44,54,130,25,187,75,11,205,162,206,39,172,207,122,17,121,162,208,79,21,33,168,154,18,131,233,165,208,7,191,106,3,88,167,218,157,228,17,136,250,4,162,1,241,100,118,44,197,74,203,199,158,159,148,6,97,19,103,186,13,125,209,194,233,128,160,175,92,121,69,84,40,175,41,1,189,167,28,129,116,84,62,77,4,45,247,212,153,180,176,248,85,220,138,140,254,158,110,93,71,76,229,110,127,230,35,86,48,57,183,190,249,80,127,250,6,118,206,235,65,142,86,216,78,93,126,135,218,189,180,15,222,75,37,44,176,152,176,40,137,166,216,118,100,254,175,6,215,165,40,70,46,41,145,175,73,212,145,74,239,36,202,203,44,72,1,95,210,255,69,130,250,152,232,3,53,251,26,215,197,77,1,196,1,143,100,140,169,22,106,90,150,246,41,221,102,239,14,233,207,91,112,213,97,175,16,124,49,115,136,13,232,252,14,74,48,201,87,165,140,53,95,234,212,239,122,176,39,131,181,78,217,62,201,118,143,153,80,122,172,166,126,137,205,190,222,206,32,232,253,142,126,107,224,215,150,33,145,234,37,211,65,27,68,130,5,182,150,109,210,246,185,64,185,202,61,182,47,110,92,33,148,183,132,78,235,145,12,251,83,20,22,110,15,172,46,63,78,254,18,105,217,243,99,252,172,159,128,34,194,208,192,164,58,249,85,251,218,198,68,19,74,201,228,206,49,28,31,60,252,201,103,250,183,15,218,100,246,249,57,53,85,100,131,171,131,229,231,88,10,235,54,236,119,91,98,62,144,48,236,92,89,164,80,110,216,234,191,97,60,149,23,131,50,40,245,160,122,60,37,220,31,183,138,15,83,69,247,123,165,4,31,245,102,145,65,230,143,224,178,146,0,252,129,39,70,218,225,245,143,190,191,109,172,65,169,101,213,66,124,10,162,41,38,168,63,16,103,18,8,62,46,164,102,169,219,165,142,126,34,198,197,247,131,171,127,163,16,191,58,93,249,219,218,124,81,150,201,74,173,84,114,199,201,106,137,37,65,7,107,245,251,138,239,111,212,63,183,190,2,51,77,120,78,75,29,233,194,95,162,93,48,62,249,49,131,153,193,176,43,212,74,8,99,63,251,107,127,150,13,209,52,171,95,173,107,53,94,132,22,164,151,200,80,181,199,205,65,50,197,196,105,9,161,237,101,176,120,196,194,184,113,134,68,109,87,84,206,146,158,91,140,96,132,215,213,177,139,60,246,152,135,23,242,127,216,234,75,54,250,64,205,151,208,143,226,126,215,134,82,203,162,123,233,149,153,42,6,43,109,246,77,157,63,217,60,169,185,135,253,104,187,97,243,2,91,40,105,128,82,160,160,54,195,175,85,79,98,171,46,176,68,42,74,174,244,190,138,82,154,221,121,248,121,57,147,81,47,65,154,130,192,99,22,181,148,252,103,42,45,44,205,41,156,51,239,102,0,156,10,114,10,164,107,141,191,194,187,150,126,5,239,21,134,89,58,183,87,120,140,15,213,191,50,31,36,180,91,30,170,89,34,196,34,84,220,139,245,149,16,39,153,197,111,52,24,153,118,190,147,11,24,52,91,216,249,4,13,227,137,85,78,191,50,18,226,237,129,172,115,131,19,75,244,76,53,76,149,180,246,222,249,228,226,42,229,120,242,81,148,188,70,42,125,170,175,187,90,48,154,42,124,1,201,66,184,254,34,217,99,34,56,229,35,117,13,202,222,12,251,148,109,117,177,72,213,207,179,221,51,200,250,63,176,174,22,226,79,32,167,182,254,98,75,230,154,211,102,41,24,143,252,30,119,219,65,86,238,82,249,80,91,109,69,76,102,55,60,79,53,180,43,156,221,158,171,200,160,117,89,125,186,98,151,37,123,55,171,188,55,130,231,17,6,248,153,45,13,64,155,209,50,105,227,206,147,222,85,60,77,103,125,67,30,60,221,104,176,116,110,247,206,16,139,177,138,125,53,24,139,57,88,241,73,102,115,83,212,155,208,109,222,10,18,176,136,121,57,224,11,215,35,27,240,98,54,74,151,71,226,218,140,231,127,80,242,242,35,130,149,235,109,79,177,228,71,150,215,166,74,203,215,138,91,53,87,215,47,204,248,93,87,136,163,127,243,124,58,188,27,8,152,133,192,236,1,83,217,242,6,18,168,110,64,242,179,49,9,11,82,194,143,217,184,130,145,255,67,46,254,117,203,103,150,161,188,222,33,82,234,248,15,167,91,91,134,224,110,54,155,145,243,90,2,116,154,32,152,52,90,70,155,34,150,110,100,82,93,202,36,61,195,227,143,236,68,131,154,235,15,184,130,157,158,105,50,1,126,137,166,185,39,101,166,216,135,55,97,114,250,210,212,129,107,191,214,124,45,156,238,73,5,182,110,174,50,176,207,124,49,15,27,58,208,62,73,206,193,79,88,91,43,242,251,241,16,156,31,71,173,44,36,81,195,41,76,228,200,22,245,226,218,77,195,31,70,179,212,226,212,144,244,0,15,56,63,65,225,40,84,165,221,248,107,239,171,233,250,154,44,55,49,11,178,146,99,71,82,110,229,228,217,208,154,6,244,165,212,111,3,219,185,141,8,56,112,134,211,168,63,89,200,73,180,69,99,108,212,242,97,52,13,149,202,176,226,202,68,217,191,161,145,134,2,83,0,151,150,98,191,232,213,223,115,181,212,159,203,121,182,187,13,18,223,102,79,221,85,43,95,217,78,192,211,122,198,8,94,120,170,79,150,24,40,55,101,72,206,12,74,174,105,238,76,22,115,202,89,197,227,193,3,169,45,146,217,41,3,54,185,41,89,125,120,145,65,22,210,91,235,149,251,227,73,191,123,76,28,230,76,182,181,31,141,215,248,225,110,113,219,16,157,203,191,184,102,129,27,82,28,13,86,35,150,77,149,100,38,133,59,100,1,217,155,103,86,8,15,104,100,233,234,91,29,36,111,56,79,15,16,223,4,241,25,49,15,59,135,172,21,79,152,40,141,188,17,33,118,18,30,249,216,193,105,55,221,235,202,98,178,129,20,158,71,59,43,91,104,40,165,169,233,246,127,111,233,21,119,179,50,253,204,159,107,69,209,162,34,244,238,41,69,184,210,59,206,255,113,75,120,224,53,149,10,252,177,125,211,203,103,46,55,49,205,144,58,108,143,116,91,27,208,152,249,179,65,206,224,174,195,174,40,59,206,215,26,37,229,225,159,225,134,240,96,79,84,210,127,146,104,217,135,47,119,78,134,207,62,52,35,10,214,17,120,153,134,13,42,145,70,53,211,131,171,83,224,4,67,219,156,172,198,154,214,235,33,59,166,148,58,168,104,199,221,98,148,230,112,4,232,245,199,25,163,23,119,42,115,23,203,154,208,69,232,224,169,120,68,60,194,158,245,28,66,198,71,170,22,154,109,69,215,162,81,245,126,132,35,45,114,207,153,34,194,103,90,12,162,165,192,16,183,159,247,231,87,159,55,7,237,1,185,16,133,211,186,110,232,153,253,110,93,120,155,221,197,162,161,158,95,169,37,23,8,7,116,112,240,63,252,176,188,22,183,155,190,170,246,105,17,205,95,22,114,31,203,80,191,156,70,165,85,173,150,122,63,213,100,103,97,138,162,151,177,232,139,92,160,89,179,183,107,197,99,229,232,10,65,13,233,118,155,6,87,185,104,109,210,250,25,60,200,110,0,35,157,56,235,183,60,167,16,30,106,71,68,163,144,182,56,127,148,103,28,223,239,250,73,50,109,46,156,128,199,47,191,22,22,61,135,225,190,67,134,157,27,113,212,73,138,63,55,21,245,253,155,212,166,130,175,211,26,59,128,5,108,112,133,180,28,183,233,103,79,21,131,17,42,166,171,85,25,143,224,27,52,248,112,7,97,205,132,246,133,31,126,163,230,52,32,64,29,249,165,30,212,86,216,227,200,143,84,132,18,70,230,109,204,233,141,221,247,163,140,104,250,188,165,252,223,81,102,156,116,77,7,251,186,19,254,206,1,57,227,9,168,230,67,204,157,215,138,157,109,164,65,126,108,24,233,47,23,101,217,245,100,191,43,120,229,90,173,70,3,154,82,207,144,28,140,201,20,101,140,226,21,197,42,162,41,20,207,97,8,25,28,16,16,218,172,187,31,108,70,250,136,225,85,88,164,102,98,196,135,30,153,246,159,124,135,95,155,12,233,212,158,126,192,53,101,85,202,99,172,255,181,74,15,123,117,237,135,228,72,37,36,209,39,217,99,156,79,241,60,120,125,204,47,40,25,47,139,225,26,85,17,216,6,205,22,119,19,51,189,199,215,219,100,170,140,151,158,35,184,107,39,173,216,223,73,28,65,210,31,186,219,120,69,194,121,243,162,96,205,205,193,213,29,238,152,108,64,126,204,206,236,5,97,59,77,162,126,142,237,232,105,69,169,18,87,206,133,236,181,127,99,136,49,28,203,140,120,70,154,60,248,154,83,253,148,102,59,156,235,83,65,52,202,128,155,193,223,236,167,52,113,114,9,18,164,210,125,239,190,34,250,34,125,247,202,181,150,132,149,214,204,81,194,169,201,117,255,247,47,87,185,188,64,252,234,184,226,232,31,173,97,241,135,108,240,184,241,81,136,224,207,187,1,177,67,228,65,2,61,150,184,191,190,175,112,52,104,59,186,206,52,96,71,68,204,59,179,104,15,38,245,157,48,169,226,75,143,27,97,114,163,108,192,133,163,133,232,47,13,247,204,195,87,99,87,203,246,65,142,126,232,183,247,228,71,170,16,209,57,138,156,246,126,123,248,6,63,124,170,97,246,145,6,101,176,213,105,200,123,116,94,117,1,95,235,55,84,72,203,68,169,26,103,154,144,83,93,52,205,216,104,136,9,235,72,55,195,212,131,93,107,123,0,207,255,196,150,0,110,33,225,223,94,186,31,115,185,205,128,87,227,73,246,180,219,26,247,208,212,220,204,90,182,100,254,187,80,14,32,197,219,153,42,7,115,101,58,241,49,245,142,218,0,214,24,234,229,37,253,54,245,121,34,110,233,10,31,154,4,144,38,130,15,82,28,224,131,39,122,245,73,56,117,233,226,96,61,143,180,61,58,255,156,75,139,77,77,238,3,74,42,144,157,56,165,247,216,139,33,94,233,84,226,241,145,198,158,194,158,6,82,227,184,43,248,241,189,130,157,53,22,240,232,128,210,57,16,63,180,217,13,237,235,187,231,197,37,37,50,100,249,112,192,160,169,119,157,215,63,219,106,218,6,170,11,223,118,105,10,61,57,107,167,90,81,26,96,221,58,61,121,116,0,187,19,148,79,104,65,74,235,178,89,126,161,4,136,82,104,195,9,174,40,176,79,155,200,52,0,253,235,221,184,175,113,131,123,69,124,135,75,81,6,235,1,95,128,165,5,239,79,247,128,111,179,246,231,32,75,215,83,131,229,61,67,154,207,156,227,217,117,148,99,101,161,25,146,230,223,51,164,205,105,164,185,230,99,82,211,53,217,181,82,218,76,187,136,190,148,169,26,41,48,2,86,222,160,3,15,205,186,142,218,165,193,221,163,140,64,33,121,105,242,48,115,134,187,100,74,71,110,78,28,61,156,50,52,203,190,143,69,121,199,34,195,87,2,117,79,73,2,46,138,145,21,130,229,166,138,108,71,176,49,163,49,244,199,231,219,143,159,233,152,104,28,43,31,39,157,115,204,131,207,174,144,231,167,213,201,90,88,242,241,188,82,161,107,27,235,188,111,76,34,19,191,59,83,42,62,238,144,149,21,38,184,84,200,97,46,63,62,14,246,68,140,60,226,205,81,77,21,29,83,250,41,211,206,178,161,116,97,196,107,59,169,19,194,248,238,246,222,201,63,125,141,117,37,25,236,236,117,55,69,87,105,70,122,76,50,121,227,173,136,106,183,217,187,149,123,69,6,144,10,69,21,93,121,17,121,123,130,140,98,155,239,82,210,164,82,120,48,44,113,248,106,155,93,123,249,66,169,26,225,43,193,223,178,47,63,71,139,140,125,189,116,118,206,36,66,133,120,233,42,91,70,219,246,159,134,11,52,19,127,203,199,140,41,44,200,83,63,101,25,136,235,226,239,93,113,121,163,189,235,29,175,113,26,9,74,99,160,142,184,46,201,242,48,131,131,110,60,179,169,88,231,24,233,190,215,16,125,214,191,91,175,231,236,80,207,173,23,229,72,106,114,89,175,56,21,18,89,241,17,182,97,205,146,19,197,187,143,182,158,91,196,176,40,49,208,157,102,238,103,167,226,175,235,132,106,8,57,227,66,95,105,155,210,206,84,63,51,183,254,87,151,99,152,20,175,155,126,140,180,44,53,70,31,75,33,235,29,222,216,74,27,131,134,164,196,80,105,163,105,234,60,188,150,220,174,47,113,184,86,207,149,125,162,126,29,205,215,20,236,61,131,183,98,183,237,180,242,157,123,225,103,137,250,55,74,27,243,130,152,37,97,106,219,55,64,163,244,146,226,108,98,181,188,239,59,91,71,119,137,18,196,230,190,242,98,154,128,242,78,124,112,21,205,80,19,50,11,13,57,160,241,111,87,129,194,178,17,160,217,152,25,200,149,81,213,221,30,96,183,78,15,76,129,62,126,24,153,223,179,0,158,108,193,144,31,233,175,215,129,83,89,146,4,103,91,45,45,147,45,116,155,234,56,253,241,198,110,63,39,112,129,19,185,148,119,45,95,213,150,150,214,60,11,37,236,248,228,242,164,5,49,199,231,83,28,214,153,19,227,209,163,168,254,47,78,114,124,205,73,46,39,159,42,179,99,50,14,99,225,114,189,249,49,227,80,239,248,237,173,55,252,195,74,63,125,131,7,209,228,43,206,137,60,21,239,52,159,118,43,137,147,85,121,31,207,58,15,6,114,104,207,143,182,3,156,188,243,210,54,246,145,159,29,179,219,185,196,224,200,201,72,46,191,55,79,112,228,53,158,28,215,23,117,18,202,227,42,190,246,51,45,72,142,78,32,202,65,120,196,233,156,158,52,132,65,103,140,254,80,222,156,27,64,139,55,81,242,36,198,247,27,209,45,21,126,47,83,181,170,48,43,195,141,185,94,87,245,218,144,243,104,216,118,59,31,18,223,197,3,215,183,43,19,209,68,28,62,120,45,253,211,170,92,167,228,245,172,22,9,182,169,48,0,170,22,180,182,241,233,87,193,203,208,154,126,250,127,193,136,38,3,150,25,113,81,220,253,236,54,98,12,128,149,23,150,240,164,125,69,40,196,107,186,20,234,18,34,117,60,166,210,195,23,120,210,61,234,94,78,43,152,3,25,194,78,117,30,163,224,130,62,220,57,26,109,89,33,9,249,253,216,69,248,99,241,171,130,15,217,234,49,151,133,54,217,134,17,128,41,231,151,177,119,32,247,18,70,135,15,3,41,159,157,170,70,122,232,206,36,80,134,228,240,41,153,109,20,54,169,142,27,229,48,161,108,192,121,168,192,150,28,148,50,238,39,208,39,104,3,90,147,175,106,17,126,208,64,120,161,52,242,253,94,205,29,24,107,106,173,85,202,56,207,235,61,63,124,28,17,28,147,38,128,5,131,28,230,119,73,225,165,200,199,45,36,166,177,19,37,69,123,221,120,242,38,204,219,91,130,95,149,151,169,21,223,120,149,170,228,159,197,203,64,255,205,61,190,92,115,15,178,90,14,18,12,128,213,3,44,27,35,3,115,145,185,75,174,196,96,239,206,137,197,220,193,224,229,54,50,229,87,19,205,6,202,18,40,171,65,108,241,177,171,211,221,109,65,183,228,16,149,74,173,145,231,105,255,31,23,103,225,22,245,246,117,113,5,148,238,161,187,81,90,186,187,59,20,149,46,1,105,233,28,144,28,186,67,201,65,233,238,146,238,6,65,186,81,58,134,28,96,152,121,31,244,222,251,187,247,125,30,254,129,195,222,103,237,207,90,251,124,39,198,192,249,76,141,10,120,39,80,252,114,24,240,220,236,167,180,78,200,172,236,220,166,138,221,187,62,137,164,102,22,140,51,164,27,136,199,167,48,149,53,81,101,91,237,246,223,217,192,137,225,62,48,232,177,76,200,25,18,197,16,141,142,243,2,89,77,6,82,3,163,51,19,208,29,49,117,223,8,129,110,197,96,103,106,243,77,116,168,215,61,226,5,253,218,162,144,231,35,239,195,67,205,199,190,200,97,124,165,162,32,239,193,120,241,226,196,226,148,199,133,141,81,36,82,117,2,187,55,209,53,253,37,31,82,109,100,19,204,48,77,227,72,44,52,224,255,77,183,43,236,199,100,33,87,216,250,41,207,145,232,39,71,209,236,231,95,91,95,139,75,12,192,175,83,11,237,251,93,163,150,167,117,126,126,247,220,148,43,45,45,181,95,78,15,242,88,4,109,29,205,131,24,202,91,94,10,172,89,202,91,252,232,102,206,2,25,184,39,78,243,40,222,8,156,88,6,154,57,70,182,172,95,179,23,219,51,171,199,14,147,144,135,168,56,237,253,34,157,213,100,200,168,117,185,108,132,250,98,234,222,201,202,106,33,206,57,19,228,99,157,206,53,148,3,228,184,173,98,183,227,182,185,94,222,182,32,188,78,76,7,148,52,174,215,72,129,246,243,122,214,223,79,177,251,188,161,156,83,50,236,226,130,184,107,207,74,250,60,84,197,83,59,198,142,194,94,49,68,26,187,49,159,104,206,255,20,160,72,34,93,192,88,99,21,249,0,51,245,203,41,234,15,155,122,29,114,66,24,211,89,6,174,200,226,207,103,109,20,118,248,79,52,111,170,249,192,92,44,23,201,250,191,51,122,47,219,213,23,173,144,241,61,143,45,241,137,69,10,39,123,176,10,223,170,95,95,134,46,205,76,161,34,137,40,60,61,248,112,180,56,252,173,250,53,14,90,80,11,187,49,239,117,221,227,136,69,92,4,141,217,100,128,86,80,175,211,43,173,102,226,22,188,247,242,233,159,124,153,118,124,181,86,21,85,24,165,201,245,37,188,205,123,233,59,183,196,232,48,181,238,55,105,142,2,57,24,40,201,21,97,138,104,221,51,240,25,196,36,245,131,195,121,40,99,154,108,120,19,215,169,99,215,183,196,243,111,223,184,225,243,77,222,181,234,159,65,100,242,220,128,177,210,175,9,54,76,169,185,6,142,216,124,128,141,128,228,147,151,46,236,55,172,211,213,167,63,159,80,167,57,145,159,198,208,179,139,11,2,120,65,79,103,58,77,123,157,136,46,195,242,148,120,35,85,244,213,37,254,27,2,217,33,189,64,251,198,207,240,245,225,58,154,161,252,104,175,158,58,14,216,126,210,122,86,169,185,144,169,159,54,217,171,195,202,94,148,110,179,210,146,66,37,225,24,145,245,161,91,72,116,127,210,44,151,80,197,99,159,93,198,86,27,169,63,183,204,107,12,3,155,139,107,79,104,185,187,39,90,237,245,47,176,2,172,123,93,23,27,83,75,188,33,59,228,7,173,200,132,166,164,120,137,164,49,255,184,97,149,122,108,72,175,100,6,225,183,177,144,156,176,62,155,202,161,164,79,47,65,20,47,221,254,94,212,181,32,118,225,173,78,253,52,20,130,142,13,123,181,59,22,67,205,68,237,176,101,63,118,73,253,86,155,148,89,135,226,158,121,150,126,65,131,184,142,51,241,200,235,202,38,135,62,241,195,65,116,89,63,226,41,103,118,225,129,14,124,110,98,247,147,225,52,183,255,111,235,26,152,105,131,39,127,200,213,113,33,209,79,154,163,143,250,184,84,175,56,207,185,221,29,124,171,181,103,72,149,0,57,93,224,161,234,17,76,230,226,238,234,91,176,80,139,46,142,167,191,232,18,241,220,152,102,202,171,58,189,60,203,34,7,16,242,248,179,40,154,9,2,14,252,134,102,47,41,158,25,233,140,20,214,228,121,85,70,10,90,233,38,48,249,106,66,227,133,83,140,72,129,50,232,50,22,241,251,133,195,17,26,176,89,248,36,129,138,145,236,189,230,25,234,88,208,25,197,24,125,72,200,8,250,208,154,86,237,192,55,245,107,154,21,32,155,29,172,11,50,119,177,179,179,0,91,228,6,204,154,11,76,193,66,185,1,179,102,134,10,138,60,113,56,49,169,20,247,20,210,199,108,20,192,155,120,244,188,240,56,154,205,167,96,109,168,196,148,51,187,168,160,189,41,246,59,87,207,51,243,255,151,240,115,60,232,14,199,229,240,65,155,188,20,74,102,103,9,255,193,81,108,120,118,109,169,163,255,226,47,206,78,2,102,199,183,17,38,239,169,22,235,108,29,20,183,242,7,10,187,209,220,6,231,165,179,89,38,200,35,222,16,43,127,87,178,178,64,1,168,216,148,176,118,123,51,122,96,198,124,97,227,107,34,113,162,238,217,81,142,95,37,34,31,37,81,192,225,234,218,18,27,140,210,189,231,177,147,134,45,48,79,202,204,87,124,184,51,107,85,86,120,84,47,121,34,94,188,197,168,177,26,76,31,49,56,131,232,230,211,169,163,25,162,113,163,104,160,24,90,243,91,2,53,224,251,63,237,232,100,184,25,121,99,209,130,168,82,63,92,187,155,40,24,123,208,92,111,137,168,65,107,66,14,28,217,169,95,45,28,171,156,223,214,10,238,104,76,54,33,87,159,142,65,222,66,191,8,112,99,238,34,92,130,29,230,115,201,115,148,123,23,228,50,95,234,125,255,150,191,51,21,247,31,31,203,231,137,244,2,141,255,154,173,236,156,240,247,107,246,194,119,227,141,20,199,153,143,45,38,237,75,75,195,35,105,159,61,54,186,9,165,12,190,189,172,210,45,136,174,213,141,163,177,163,18,169,59,135,250,176,226,203,168,71,160,88,249,224,189,15,219,236,211,99,116,54,50,143,28,229,103,25,123,187,123,68,22,142,246,206,121,71,116,166,134,135,27,193,53,92,120,86,142,97,235,237,247,219,8,233,116,152,9,70,30,111,250,43,222,199,209,35,75,25,70,51,10,41,119,55,169,177,121,77,201,106,39,9,245,199,242,142,118,15,88,232,248,252,89,182,187,33,202,47,32,3,239,216,121,4,45,60,56,222,225,151,159,62,48,219,182,103,228,171,94,181,147,15,194,74,207,50,228,114,71,68,135,59,248,218,135,207,226,120,35,112,104,4,7,177,229,97,10,83,104,164,145,62,87,147,209,224,104,109,131,255,208,154,244,3,173,185,80,185,19,211,211,34,137,74,155,14,157,213,123,44,5,215,30,238,255,166,181,185,38,130,100,12,143,125,197,98,166,221,201,246,44,42,94,151,47,89,222,195,40,172,200,62,6,252,91,137,171,117,24,217,175,51,67,58,212,104,132,45,178,238,190,88,196,144,42,180,180,207,234,50,151,243,19,61,175,168,26,243,121,157,42,109,17,55,55,225,179,223,115,114,139,254,165,239,213,101,84,199,34,141,40,70,107,225,173,137,18,94,218,243,135,235,24,176,51,121,207,226,88,212,198,162,43,19,242,253,62,237,202,56,13,192,225,7,211,110,108,94,125,39,22,231,4,152,210,66,97,152,250,56,87,133,98,116,164,178,84,101,235,186,0,29,113,226,158,231,122,234,27,178,179,197,3,131,190,142,230,145,53,99,253,36,228,145,27,211,57,237,202,96,203,218,157,131,37,95,60,242,31,110,155,220,70,27,164,157,217,230,204,192,121,141,34,103,170,143,102,191,160,227,20,55,145,110,61,183,194,51,118,12,132,201,151,174,201,88,96,230,92,65,34,112,25,240,104,46,20,177,246,98,50,164,182,142,190,108,225,52,120,56,188,149,230,146,226,141,57,64,217,156,171,87,199,2,113,3,123,146,189,191,145,22,229,137,173,230,51,196,132,167,161,214,104,60,47,78,103,1,44,233,9,202,221,219,118,24,186,228,223,246,73,214,243,59,185,172,38,207,192,231,155,41,159,4,144,63,184,219,73,28,33,95,249,51,18,42,134,94,228,214,136,243,245,111,5,128,162,187,184,227,14,114,96,114,92,199,254,254,62,36,6,124,147,46,143,194,160,253,233,101,157,41,228,249,82,85,128,69,52,98,222,127,221,43,7,244,25,71,244,245,69,49,90,100,53,195,221,124,46,124,229,104,16,18,252,61,26,156,221,126,100,244,125,225,252,224,191,158,247,249,195,5,77,241,177,114,51,164,167,69,242,149,11,196,189,110,92,149,28,169,248,118,68,102,208,254,222,200,39,89,49,65,143,118,211,36,77,227,200,225,76,219,226,112,52,137,121,61,168,93,81,25,93,171,66,73,85,229,177,100,124,141,179,62,118,136,227,35,109,101,179,245,167,212,0,220,35,70,108,21,227,60,196,100,83,47,249,119,129,217,137,205,162,209,222,247,238,248,184,64,61,109,64,230,176,18,169,158,36,151,177,33,134,14,23,119,151,172,228,22,244,239,116,218,144,57,36,62,30,54,123,175,120,109,18,35,105,136,211,214,7,181,83,189,39,30,101,45,193,102,208,62,250,96,80,69,250,148,129,52,230,71,143,214,246,120,56,45,235,144,124,20,38,89,90,253,151,131,30,194,56,83,173,20,236,227,185,177,216,192,188,193,180,172,115,39,192,236,235,53,99,163,124,202,191,190,48,251,235,175,243,241,131,200,62,110,127,84,98,140,34,103,122,130,63,95,231,29,37,14,237,141,242,216,90,153,88,236,209,236,208,33,69,29,182,127,230,113,58,24,224,177,159,12,17,248,89,52,245,163,68,157,255,121,92,184,239,173,95,95,252,69,244,9,238,181,24,223,218,192,150,127,6,36,76,228,177,196,41,239,243,179,41,146,60,172,81,222,232,34,126,103,201,110,12,42,126,87,31,121,53,146,155,34,89,173,251,237,4,111,150,204,121,33,203,23,132,136,110,175,162,171,129,119,121,112,197,61,186,27,221,196,124,78,246,71,242,103,115,179,223,31,229,61,212,16,2,6,245,211,112,82,249,73,85,139,110,85,250,180,53,243,222,55,63,225,198,41,63,117,34,28,59,127,35,159,174,125,241,20,75,126,150,175,201,60,90,113,33,184,28,247,202,175,99,6,33,36,182,45,20,87,155,252,244,226,248,157,34,213,139,153,48,236,146,234,141,96,159,133,162,188,111,101,154,19,156,163,207,254,139,178,119,49,15,184,135,93,255,156,224,49,254,188,62,10,148,120,231,210,115,180,138,226,248,147,89,233,92,133,34,63,95,11,180,242,179,173,143,219,137,233,128,166,200,224,120,166,200,234,237,140,219,128,110,51,11,58,3,118,246,180,236,155,110,22,143,16,95,133,146,55,7,12,70,26,135,6,40,173,249,34,159,48,108,39,240,110,240,142,125,217,41,218,13,129,150,178,42,175,69,253,200,104,222,138,235,117,244,124,56,222,172,188,218,49,154,0,254,217,52,252,65,3,193,126,28,219,42,60,81,137,219,83,200,147,43,126,184,208,233,22,23,167,180,24,33,111,228,47,142,110,123,112,104,169,189,68,67,125,148,254,124,139,251,107,31,156,57,214,10,99,17,13,26,186,77,2,243,117,89,158,9,37,78,19,202,173,220,231,20,147,133,165,19,172,155,141,32,5,172,99,116,11,237,152,203,147,96,72,201,127,151,16,135,200,72,47,208,142,144,139,158,235,160,200,153,174,17,190,238,112,169,93,185,110,20,246,152,45,215,92,138,38,33,110,9,10,194,157,95,192,211,53,50,178,10,95,71,238,44,164,146,236,98,166,146,232,126,11,25,162,68,247,35,142,148,76,223,81,188,244,178,137,99,208,120,78,44,184,184,14,18,167,112,74,39,196,61,246,235,140,11,247,90,163,5,216,66,249,38,28,198,123,62,130,9,222,61,135,241,228,72,95,162,146,59,211,41,57,143,168,16,154,71,249,155,51,236,140,242,153,247,154,252,78,1,20,207,72,116,8,192,9,211,73,103,58,215,57,77,113,187,240,207,199,25,171,236,96,119,192,181,86,136,45,12,223,34,246,158,31,190,30,13,206,112,37,158,135,189,29,101,237,198,84,61,231,201,143,168,141,250,209,146,199,122,91,30,103,155,232,194,26,38,214,52,112,103,181,61,123,214,74,117,85,90,70,147,154,17,229,4,232,187,6,133,245,188,230,203,213,20,52,182,253,239,43,128,121,135,135,115,11,136,88,1,30,227,11,225,161,252,26,53,122,47,184,34,222,131,248,241,173,186,89,203,173,183,154,207,116,47,166,194,163,187,26,117,129,140,133,202,124,165,213,29,109,11,137,166,242,123,176,39,235,84,252,167,219,199,77,90,44,86,79,84,86,119,182,132,238,209,226,172,61,199,73,186,207,212,176,95,55,148,14,151,152,149,153,182,81,240,210,211,93,145,198,19,12,80,111,38,116,243,227,149,152,192,190,27,116,217,11,79,237,182,165,20,221,203,75,14,115,127,12,191,53,137,32,26,162,57,225,236,164,189,41,253,35,73,124,151,16,125,127,255,111,99,159,122,156,0,93,74,33,25,114,245,220,164,99,193,93,187,151,245,20,221,13,35,20,121,29,126,33,102,72,38,2,42,91,35,243,235,237,131,27,200,78,137,206,254,62,30,193,121,54,241,49,148,211,75,105,57,91,101,224,32,127,254,124,214,221,93,253,127,169,211,122,57,218,32,237,197,171,16,0,23,18,189,115,39,122,91,108,227,243,19,31,168,119,43,121,109,208,175,182,150,153,156,132,243,165,74,63,1,199,24,167,199,234,148,130,51,26,162,102,153,84,18,102,69,20,31,96,111,200,53,39,248,246,79,13,196,47,180,243,122,245,185,15,18,64,132,90,120,128,88,205,5,183,101,79,100,141,51,69,117,252,212,233,95,32,54,248,23,227,47,63,131,69,222,203,124,197,198,190,100,13,11,248,162,117,63,46,243,151,40,253,105,99,253,45,220,152,142,6,73,120,38,186,236,20,236,73,186,242,5,121,106,246,57,153,252,136,61,54,182,252,163,95,165,54,50,126,80,188,217,129,18,58,85,191,215,195,16,142,1,48,245,130,169,63,68,28,204,192,140,213,95,227,250,13,70,33,207,240,116,110,62,55,64,60,93,245,191,222,25,3,233,5,26,17,235,54,254,239,159,127,231,221,97,175,57,112,4,246,59,2,119,189,151,2,153,54,187,155,146,168,11,204,202,200,230,59,250,53,68,60,162,179,68,172,62,186,239,205,172,50,44,155,246,16,22,151,132,77,21,82,223,178,136,49,125,95,221,210,28,135,224,101,209,100,202,42,83,93,101,159,185,238,232,80,243,29,152,206,10,139,217,20,182,45,108,225,174,176,227,224,110,176,183,38,76,161,49,213,96,16,23,220,246,253,105,86,22,20,240,182,211,50,219,48,160,177,5,49,169,20,249,107,195,33,88,112,204,185,5,241,30,150,7,209,183,133,13,145,201,159,147,108,82,200,71,233,223,212,184,26,134,57,142,29,56,125,25,79,236,255,76,234,246,107,195,38,90,146,231,109,127,58,127,127,7,86,113,205,42,63,213,145,82,27,55,191,159,150,38,5,255,23,146,119,68,151,117,93,247,86,172,42,230,138,20,255,122,118,227,130,98,137,247,222,37,205,144,133,29,41,69,221,116,246,211,165,199,1,114,237,209,167,165,236,134,230,215,175,122,176,185,160,49,229,111,90,5,28,14,139,122,194,238,236,115,209,45,158,66,132,231,114,34,140,10,123,5,153,196,153,82,231,186,120,157,109,223,97,152,231,101,238,16,186,138,145,91,164,61,165,62,244,245,120,250,130,229,170,250,162,53,45,67,55,117,110,194,42,106,83,73,12,189,54,36,92,190,75,213,46,126,31,247,195,102,220,175,132,69,100,181,164,121,237,59,93,196,136,206,147,49,233,51,212,51,157,51,253,107,154,171,39,171,98,238,136,89,168,236,86,165,17,25,112,188,187,145,119,135,235,173,99,125,148,13,235,199,46,52,133,252,151,233,218,51,129,50,134,21,189,185,128,158,233,26,8,106,155,159,45,232,62,166,159,158,121,111,54,191,150,138,199,49,62,38,48,129,245,29,209,236,124,252,99,126,181,255,60,37,152,140,70,31,164,157,137,230,170,208,80,71,249,68,16,196,146,147,101,61,183,38,188,114,236,237,22,235,176,106,152,182,106,31,205,187,46,123,176,30,36,126,152,188,53,176,117,98,122,48,217,78,37,115,170,247,217,152,163,162,155,144,115,46,117,224,188,28,117,224,187,243,54,7,82,81,166,83,114,152,102,223,96,60,160,150,61,150,147,235,238,87,232,215,170,136,13,156,85,235,10,140,218,248,180,210,91,170,152,223,91,80,101,184,18,92,134,178,96,73,165,61,7,240,248,193,152,148,66,20,23,72,57,220,1,49,29,66,187,88,60,143,33,213,130,253,57,19,223,234,88,223,1,56,222,38,52,148,218,243,191,3,204,178,216,37,225,38,217,18,109,50,153,102,237,205,85,70,40,134,85,23,233,55,198,190,246,113,140,152,96,221,188,6,217,112,147,63,151,77,248,62,253,47,148,229,67,125,224,216,240,210,34,87,188,32,102,149,245,122,171,202,37,7,220,209,238,198,160,236,234,190,145,185,222,55,235,197,51,57,113,121,98,123,51,121,229,84,174,189,104,162,174,251,121,2,148,52,227,151,55,130,124,221,189,8,175,218,121,26,251,17,164,221,159,181,156,13,217,220,55,205,159,221,113,229,253,42,162,92,160,59,111,210,99,198,83,4,177,190,210,0,133,88,103,113,21,54,43,175,6,36,250,29,55,238,145,36,139,213,229,80,101,13,49,206,244,12,20,121,157,98,7,4,14,186,255,92,69,239,90,101,141,107,154,193,167,43,64,58,122,126,56,45,74,76,199,149,23,236,102,57,42,202,111,168,249,173,95,142,205,234,102,138,68,190,205,207,231,156,226,225,1,169,161,78,237,44,186,112,104,167,160,160,228,225,70,216,196,228,241,138,232,226,212,22,234,18,55,66,65,27,59,53,231,192,65,22,245,189,2,126,235,191,103,9,31,211,195,73,191,150,126,181,32,10,122,39,101,58,146,234,227,107,127,107,216,122,117,101,235,129,176,224,186,149,229,172,31,113,180,57,69,157,124,78,193,83,214,152,21,187,32,197,178,126,39,229,176,212,160,172,249,165,130,136,245,6,210,57,204,212,92,2,169,12,26,113,241,166,179,10,44,42,191,138,123,244,181,10,150,59,98,196,133,33,9,7,80,226,235,233,88,167,237,60,242,238,46,171,190,66,17,154,172,105,251,103,49,255,160,50,27,234,98,107,210,213,179,127,180,198,188,109,208,17,191,71,141,70,34,53,142,206,181,55,136,18,200,105,88,51,252,206,226,166,249,73,148,126,167,82,221,240,47,179,155,230,20,182,185,13,110,85,212,163,126,58,242,159,98,104,146,182,48,117,100,124,100,219,231,251,83,229,200,237,218,201,239,0,27,119,114,153,218,189,39,68,255,121,125,160,199,252,152,44,228,249,121,203,110,145,92,238,2,254,235,64,65,2,167,118,235,2,46,204,70,191,203,22,24,229,161,65,251,253,194,87,93,223,207,126,23,54,190,75,202,91,144,188,165,108,248,232,33,222,105,21,217,136,141,115,156,102,190,31,252,98,96,50,194,67,28,64,163,69,246,51,174,220,113,7,253,14,251,236,182,214,110,90,175,235,132,147,204,147,116,24,213,48,117,8,86,135,43,205,170,224,159,205,77,80,4,215,66,97,28,252,205,5,97,70,189,119,209,158,212,127,146,187,85,141,77,9,36,220,99,222,22,68,124,248,113,71,114,10,32,233,152,15,254,40,140,180,199,22,246,147,181,205,65,111,17,234,170,253,2,48,54,48,237,138,121,42,62,241,36,42,109,233,44,197,174,145,12,225,130,71,37,46,22,128,121,147,70,238,215,88,65,117,164,52,206,218,205,14,78,144,181,101,220,183,98,48,99,79,252,119,142,44,84,133,98,137,39,82,5,123,217,138,198,103,135,244,249,148,35,247,142,6,56,229,216,118,240,198,215,109,145,173,2,233,180,17,231,192,214,187,11,232,151,104,125,88,244,216,99,63,217,197,3,166,157,95,246,178,244,21,220,116,207,135,16,118,10,121,1,24,207,83,117,249,73,14,34,194,32,74,238,239,253,89,235,37,230,154,124,162,221,110,50,220,115,200,212,23,125,242,149,70,179,252,150,151,122,29,239,247,107,197,25,220,73,46,70,96,226,110,50,204,202,174,83,242,193,101,89,233,118,102,189,192,21,240,107,203,131,160,162,226,146,161,163,133,158,94,224,63,129,141,71,152,69,15,142,235,250,198,43,110,133,79,181,32,24,113,76,181,159,93,231,244,141,112,231,219,224,188,3,112,24,30,243,70,254,218,178,170,252,58,98,194,133,51,169,238,223,6,191,145,57,83,217,92,79,234,229,83,221,66,28,167,107,187,65,231,165,5,232,57,196,7,56,16,37,194,181,106,255,30,40,166,57,132,241,210,54,57,12,175,158,208,79,158,161,141,246,144,255,124,16,32,199,22,187,176,114,227,198,174,156,253,173,21,136,215,228,193,212,183,164,44,175,81,82,209,251,47,232,63,10,173,211,34,6,144,25,172,225,33,196,129,139,129,48,40,169,183,223,253,135,16,8,217,247,203,132,121,129,206,92,189,151,111,215,176,223,200,74,239,8,71,161,106,49,111,243,15,226,126,57,37,158,173,162,86,160,11,255,253,181,224,12,205,159,238,189,15,216,20,68,91,166,135,18,183,29,75,182,32,62,64,215,183,208,235,208,99,36,249,224,211,80,222,126,172,93,146,74,14,3,135,218,170,11,67,142,119,128,177,224,234,34,143,169,231,6,53,72,107,79,127,66,69,24,81,117,204,72,128,142,178,216,81,248,155,66,180,113,16,201,158,86,183,247,214,138,166,10,83,131,93,226,247,162,242,12,85,135,148,105,217,118,43,45,41,59,127,125,41,222,137,152,88,253,252,104,193,197,106,46,136,164,222,204,164,4,35,180,62,240,109,85,254,160,163,71,210,10,10,9,158,253,199,100,25,66,158,200,4,170,15,74,24,67,212,222,196,92,249,241,226,169,111,25,134,48,226,0,137,236,162,236,161,133,214,253,53,229,160,211,215,58,117,10,170,165,205,238,174,44,210,2,115,239,4,73,216,25,155,62,162,188,151,38,10,122,91,5,208,98,157,121,177,179,124,103,12,199,229,84,15,68,209,234,40,25,71,222,183,254,53,146,150,129,200,105,59,89,117,61,25,187,214,65,67,123,76,71,139,194,137,139,164,130,102,68,77,233,78,76,199,125,128,47,196,251,97,53,219,111,67,253,238,135,172,239,209,35,99,227,145,92,144,104,0,122,134,240,236,203,43,121,49,108,175,1,142,165,163,210,185,250,129,3,255,245,123,111,137,167,216,123,104,183,248,212,201,154,138,62,120,156,223,242,123,41,184,139,131,95,101,119,110,188,48,121,60,206,184,95,58,25,246,50,19,204,76,169,117,205,235,109,238,218,145,165,193,242,227,190,196,134,244,200,139,218,200,4,170,171,98,232,149,56,41,53,77,75,234,202,29,61,182,134,207,112,227,234,55,131,96,37,158,164,229,164,206,83,103,21,52,76,130,39,192,83,238,165,157,226,239,137,16,206,49,172,240,148,164,240,218,12,224,213,101,142,28,120,183,200,253,146,170,81,67,67,124,78,220,148,38,55,86,129,15,138,18,109,189,128,209,236,107,126,219,53,219,28,211,160,170,3,142,208,29,175,175,180,235,52,73,170,23,16,124,93,78,32,255,72,75,254,207,105,67,2,241,240,144,210,98,3,9,100,210,98,51,98,241,144,100,114,177,130,4,113,47,23,252,125,113,230,131,53,219,223,21,78,100,246,100,59,159,125,136,119,179,250,62,77,138,237,182,196,255,163,202,210,12,131,112,114,37,24,53,157,128,175,44,250,17,219,55,153,236,143,170,45,147,236,175,185,250,140,190,245,7,87,190,222,74,172,96,64,174,102,167,78,181,146,25,194,188,6,111,171,87,152,155,204,236,223,118,211,124,164,187,137,130,7,106,228,193,81,239,19,220,195,47,112,235,190,94,112,141,133,83,224,145,99,47,38,88,234,52,117,174,227,173,37,223,39,220,19,33,208,18,153,224,79,198,226,29,148,94,17,111,230,76,38,107,75,140,118,196,153,93,76,30,164,251,84,16,242,98,184,81,81,241,181,151,22,157,204,15,229,30,62,75,250,165,118,143,116,175,250,76,21,196,40,121,244,165,3,56,179,166,29,178,173,117,119,203,28,205,28,105,169,237,128,93,95,23,137,135,135,36,35,245,215,113,59,89,232,114,67,38,89,232,242,125,232,104,81,36,240,131,146,10,39,22,44,38,190,153,173,5,64,95,250,30,156,162,90,105,56,247,142,189,183,43,61,82,157,107,152,167,18,116,106,228,50,249,78,176,3,129,222,49,22,224,106,162,51,196,78,74,191,30,211,229,195,26,237,73,168,80,25,33,53,238,69,118,102,205,146,246,219,158,18,115,169,41,218,202,152,62,182,161,152,77,208,236,190,69,241,32,134,55,85,224,190,14,237,216,214,188,159,112,255,120,17,119,81,121,24,119,200,69,22,2,13,135,166,65,173,251,78,79,224,93,186,87,228,5,217,7,251,84,85,26,209,204,251,50,224,34,18,16,88,7,221,252,4,157,153,57,54,146,209,112,243,14,116,193,149,110,98,61,231,100,18,110,187,67,238,208,115,251,243,71,75,234,136,66,105,105,249,179,44,21,187,127,78,20,136,151,222,135,198,74,199,23,229,212,30,208,130,215,164,135,114,213,177,96,113,45,214,50,71,237,125,133,45,234,233,40,70,192,69,173,134,174,104,127,244,233,233,82,189,69,233,81,187,123,235,4,242,113,53,113,88,102,98,112,255,147,239,82,176,137,96,87,149,136,181,158,66,224,185,25,198,50,137,3,253,70,176,59,208,92,178,228,30,171,216,136,29,102,41,22,100,194,18,218,234,173,128,56,217,153,188,68,175,102,25,8,1,14,134,110,107,222,107,222,178,232,156,205,96,79,119,12,141,55,9,63,171,165,170,99,168,145,4,224,11,142,240,149,248,9,49,244,108,94,133,164,202,95,233,195,144,205,105,225,41,131,5,80,235,221,136,145,65,4,234,83,205,165,174,198,150,35,37,46,5,66,34,16,152,174,36,187,215,193,72,85,218,72,23,212,170,130,225,237,118,169,71,174,207,7,52,46,239,200,47,114,88,249,0,212,196,79,203,12,115,92,53,100,138,164,20,242,255,95,179,214,62,125,204,20,242,110,172,252,7,46,17,82,14,118,80,23,161,245,209,70,161,73,163,147,120,219,156,9,128,226,152,51,73,12,235,211,88,117,179,51,184,253,182,207,163,213,117,199,227,96,190,46,213,145,27,163,71,14,13,155,113,45,189,75,129,6,115,59,150,108,203,110,62,202,34,131,213,156,80,196,141,125,249,170,216,171,233,72,116,62,213,122,75,3,62,224,82,54,33,90,125,81,80,236,63,204,224,109,97,100,2,85,133,207,235,79,58,205,32,190,0,139,216,138,85,243,216,190,2,173,128,150,192,62,201,222,14,130,36,70,224,151,172,144,0,0,2,139,34,225,217,149,219,250,90,176,18,224,27,28,71,1,224,178,47,12,115,217,111,206,110,39,132,19,154,95,208,156,184,94,92,31,114,111,239,29,192,174,167,152,55,225,19,159,227,228,240,87,93,135,81,180,69,21,136,234,93,65,9,242,231,251,201,172,103,56,96,220,191,207,40,99,218,255,208,166,209,173,95,111,165,101,214,207,104,79,55,219,123,60,214,182,238,142,64,36,171,117,213,213,160,228,116,136,61,150,95,153,178,65,71,193,148,199,90,195,138,99,135,237,103,142,78,66,79,181,78,185,32,207,39,19,139,84,220,62,38,240,58,227,197,157,169,65,231,241,166,82,175,150,116,212,26,229,15,163,109,212,217,111,113,140,111,111,156,179,155,158,142,139,9,119,21,8,49,251,211,72,38,85,104,42,81,202,109,112,221,32,35,77,197,205,235,206,32,192,118,33,31,243,28,193,72,9,240,103,73,216,145,74,157,73,219,10,183,250,87,225,204,169,84,79,196,21,174,72,238,63,102,201,193,100,97,170,176,164,212,252,233,27,79,4,58,99,228,234,241,213,53,161,59,213,145,98,141,205,164,15,119,11,235,57,93,35,98,20,73,103,128,232,138,11,194,92,185,174,153,89,119,227,122,112,216,114,100,231,15,152,10,187,136,165,103,142,217,189,46,250,95,73,101,76,69,24,114,67,38,221,218,125,111,143,101,214,95,48,76,122,194,146,197,161,223,230,14,143,21,175,205,198,143,9,149,6,189,118,147,93,100,146,149,13,154,114,199,61,12,59,166,2,54,175,236,120,104,60,147,36,181,201,222,80,28,202,231,95,40,228,58,87,69,158,132,189,61,28,101,136,60,155,70,86,119,110,241,58,126,238,215,207,239,37,94,145,146,249,34,78,145,104,39,242,149,155,220,183,213,44,161,25,179,226,3,76,224,144,201,5,245,9,165,124,142,54,226,65,87,199,60,88,184,172,128,53,89,41,247,68,8,60,4,198,187,103,112,97,10,232,245,36,136,215,227,212,40,154,117,63,114,74,110,133,84,123,198,221,13,47,27,245,88,146,10,83,4,112,161,44,177,141,248,146,137,191,56,185,209,25,65,207,24,82,177,212,210,175,136,95,191,126,47,71,193,243,41,2,4,14,245,242,76,248,183,236,20,32,35,169,160,169,135,183,126,57,97,69,169,160,69,178,216,34,188,186,215,199,93,90,137,107,51,215,236,184,168,16,149,63,62,58,29,106,30,172,153,47,248,145,146,78,80,209,227,120,191,255,107,51,180,236,88,202,2,72,164,120,182,29,173,54,60,125,74,133,140,213,237,147,71,146,162,98,252,19,240,202,240,122,194,13,43,171,236,98,153,233,106,99,94,89,99,149,39,193,143,183,110,28,181,208,117,239,22,69,11,170,10,127,104,215,92,202,98,167,175,192,32,228,219,224,195,184,195,74,168,34,247,215,23,171,201,250,125,29,189,146,207,48,55,215,164,242,70,17,164,98,194,209,248,242,138,9,148,34,177,158,0,108,115,144,156,246,201,163,32,153,214,93,113,184,179,242,70,52,94,215,114,233,60,115,162,146,123,186,194,157,170,193,103,7,11,85,66,234,204,82,197,68,214,130,28,131,58,83,199,11,101,127,140,255,85,48,87,6,79,75,166,72,198,49,164,61,12,175,105,17,205,109,19,212,116,114,40,108,122,45,209,176,246,84,3,139,36,205,19,21,53,118,108,51,244,220,129,133,64,202,115,37,32,166,220,72,251,196,113,2,101,223,31,16,38,170,132,37,5,190,236,101,156,22,24,226,0,127,215,35,78,199,210,44,17,226,127,213,237,109,94,81,140,17,126,206,199,238,39,49,123,13,133,20,229,38,245,187,214,96,123,154,14,133,86,112,193,152,128,104,94,190,215,166,133,90,136,63,131,49,225,158,3,130,186,47,15,179,218,124,180,170,245,124,117,216,19,4,20,42,255,96,211,219,209,43,169,122,143,74,79,7,87,199,195,224,255,112,198,168,0,248,230,58,131,99,177,216,76,173,38,58,224,9,224,121,131,50,135,234,0,190,134,202,218,255,132,99,210,168,229,110,37,98,64,202,75,123,34,192,14,233,62,56,249,17,2,124,130,111,85,93,145,87,117,103,44,85,137,159,105,39,187,76,235,252,35,187,77,45,104,172,116,110,238,144,31,179,33,157,201,244,220,62,1,163,237,215,193,158,9,40,139,214,107,107,190,164,107,95,183,209,206,139,167,246,133,95,54,56,156,147,47,249,31,8,180,238,141,124,46,107,9,203,119,235,150,204,12,84,220,210,176,88,244,208,103,17,142,197,127,107,154,43,146,157,190,85,135,185,55,58,84,140,177,19,161,91,123,202,142,63,217,95,210,56,240,49,54,153,38,225,58,143,10,89,100,239,99,91,116,133,73,39,126,58,18,143,137,75,252,139,138,238,156,60,237,161,156,219,156,11,77,86,205,125,141,125,125,149,144,11,167,31,73,51,89,124,194,116,76,53,146,56,79,249,173,107,198,56,249,66,187,18,126,119,244,243,150,96,40,201,108,48,180,48,139,82,194,14,117,109,191,90,35,154,126,127,191,235,194,85,137,216,229,182,25,189,125,11,0,87,253,96,183,156,66,103,234,45,34,114,13,140,160,121,94,236,125,176,255,254,16,211,224,199,226,83,53,225,185,88,75,109,182,68,249,35,210,151,117,150,83,98,78,95,255,39,83,82,104,134,207,80,146,241,90,116,6,247,219,100,114,63,226,121,85,30,52,197,161,180,32,64,200,30,239,161,148,237,100,223,8,97,59,186,246,175,5,56,13,108,68,157,150,205,37,27,206,201,237,222,182,163,221,237,21,108,19,76,52,87,115,196,109,125,12,98,224,58,38,234,47,145,164,84,212,28,208,215,210,207,164,79,4,168,17,255,84,49,137,82,178,210,251,105,212,62,74,225,98,220,193,28,55,115,25,244,241,52,13,86,61,82,132,104,246,200,45,81,146,191,69,93,148,190,37,201,66,246,223,66,34,164,191,35,4,101,19,176,182,51,223,97,10,7,149,105,165,188,179,241,203,16,172,121,135,143,64,127,141,196,186,96,178,96,2,193,189,122,2,240,136,214,27,190,25,40,214,101,184,186,21,21,255,17,35,55,149,112,28,192,8,10,227,46,41,90,235,31,56,127,252,90,231,50,151,215,27,216,205,156,150,23,62,207,60,110,162,111,96,101,210,57,227,90,110,183,15,9,0,51,211,188,153,9,179,156,170,97,58,63,183,170,7,252,139,38,118,100,164,208,243,38,158,228,224,16,35,165,68,117,102,36,156,55,236,132,10,30,57,81,251,61,25,87,54,17,43,15,171,252,76,200,75,121,239,122,244,163,222,131,36,81,74,208,120,14,199,36,196,24,29,168,249,193,99,90,243,156,3,37,142,190,172,127,107,10,41,229,153,218,38,81,251,4,69,24,111,143,45,192,43,219,38,105,28,116,111,79,48,23,164,10,194,110,231,141,24,183,42,150,168,255,73,79,116,188,197,144,209,18,208,173,12,85,133,79,62,155,65,200,12,104,209,41,35,66,36,190,234,105,141,168,32,134,225,131,240,72,96,72,140,51,210,207,237,210,222,90,25,147,8,32,8,152,248,50,117,155,126,8,131,164,56,2,136,28,49,178,13,204,164,166,174,14,118,242,188,83,2,87,24,171,137,207,5,91,226,167,90,236,44,16,218,214,182,125,102,102,203,110,124,157,209,172,113,218,222,178,72,126,71,95,144,109,103,20,245,108,71,232,19,218,16,125,197,28,151,81,103,176,222,223,21,71,123,76,231,60,245,208,249,83,90,197,121,120,233,212,104,109,55,171,168,30,19,249,190,71,65,133,198,141,181,59,227,225,181,105,4,124,176,39,108,250,236,213,75,158,246,181,162,60,28,203,53,95,49,55,204,24,173,123,196,59,166,157,162,157,49,36,170,59,48,22,62,163,179,247,8,171,97,223,115,87,184,62,1,66,118,109,236,83,179,162,74,133,79,241,178,53,132,54,110,106,90,218,79,185,192,47,153,32,193,101,242,185,38,103,133,112,150,123,134,123,182,59,134,187,131,186,143,154,137,85,17,192,78,123,2,76,8,215,128,20,236,188,103,1,229,132,121,115,45,229,228,225,120,245,193,39,30,22,140,83,185,84,210,137,69,168,170,237,133,54,0,16,253,176,128,174,135,176,25,64,112,193,201,129,204,161,223,120,16,232,224,80,175,41,62,23,230,73,232,194,136,95,152,187,165,3,2,135,164,17,255,175,166,138,120,90,50,187,12,241,69,50,104,106,146,40,66,216,203,12,19,148,117,78,226,23,145,84,251,135,154,93,4,236,120,108,185,108,218,186,186,22,130,134,75,239,61,151,27,86,42,150,218,169,37,185,63,30,45,15,16,243,184,63,206,140,123,81,216,18,209,248,69,192,165,6,16,120,234,225,82,150,131,185,132,95,176,241,164,250,213,98,232,152,27,199,12,164,138,181,37,192,227,60,228,129,11,113,63,217,196,94,196,93,112,97,161,56,160,56,60,33,198,191,211,236,239,141,121,179,58,228,81,76,205,113,239,143,237,248,90,139,229,142,225,206,128,0,27,130,11,225,178,65,251,128,5,209,132,156,156,74,20,209,22,34,35,36,92,175,50,169,252,10,41,78,88,200,101,106,138,214,98,105,149,103,98,174,1,16,163,170,186,36,179,235,51,39,229,142,146,81,184,21,162,178,4,67,119,194,225,141,5,197,219,87,180,210,51,235,249,160,166,213,42,61,221,9,43,208,228,223,50,214,105,47,47,133,158,183,224,179,115,217,106,141,130,228,187,182,219,111,147,235,127,181,91,139,122,4,35,237,223,248,98,38,40,140,94,75,237,170,121,178,88,61,219,238,49,226,97,208,230,236,216,172,120,136,243,164,199,14,178,205,143,108,63,63,40,221,232,71,253,10,255,217,90,90,106,89,79,128,68,61,205,88,98,97,86,92,225,121,214,71,188,189,221,105,116,21,234,226,138,28,90,18,248,198,39,85,120,155,69,158,137,20,247,12,194,208,218,178,158,225,94,118,65,233,253,76,159,220,173,254,149,226,149,62,44,88,68,26,86,154,172,132,203,244,12,78,166,140,4,113,26,70,86,53,39,224,237,69,144,74,240,154,59,125,91,178,11,111,77,160,237,246,141,20,250,84,132,153,31,57,110,166,128,6,255,193,142,224,113,103,255,74,187,223,157,49,178,244,142,127,118,246,71,181,237,215,250,74,187,110,26,5,194,114,187,11,75,109,93,228,53,134,82,250,127,132,106,244,41,74,50,222,39,108,207,55,29,46,10,116,147,146,124,246,184,146,99,83,82,149,111,245,215,226,17,2,44,240,104,134,96,232,68,105,121,125,165,241,218,59,207,213,15,49,14,75,77,34,1,190,25,146,219,249,31,151,157,222,49,169,10,77,9,163,169,175,13,93,231,126,130,19,38,73,186,226,125,249,197,207,236,151,115,114,217,211,180,214,216,134,93,90,245,179,80,21,117,224,9,231,233,128,155,191,57,178,41,41,244,122,147,162,72,117,4,73,87,15,95,99,131,235,70,247,175,41,229,178,20,127,248,116,76,201,140,205,38,191,154,227,78,21,207,212,128,80,104,168,91,68,249,217,233,38,198,18,35,165,5,178,187,241,158,97,223,245,151,171,154,142,77,224,102,199,38,226,123,23,98,195,215,98,205,171,16,149,1,244,180,28,115,8,204,201,24,213,210,130,234,96,153,12,162,223,23,11,200,149,100,33,34,37,154,87,130,189,96,235,216,223,127,126,16,120,50,223,222,62,85,152,105,231,100,28,27,162,157,207,161,15,142,120,84,242,143,77,208,126,176,9,249,142,133,1,163,106,10,235,125,223,194,143,86,7,174,151,8,39,58,204,182,8,153,8,78,164,105,97,167,175,240,174,86,72,209,221,238,212,13,28,86,151,91,0,180,42,218,216,66,72,110,54,109,14,177,193,120,236,204,20,167,113,57,153,53,67,115,247,51,54,81,86,41,115,168,37,18,229,47,235,122,89,48,178,208,202,92,22,145,136,127,120,215,12,52,86,225,206,182,153,199,190,221,187,237,54,57,27,136,221,165,98,148,152,65,60,10,255,203,254,84,66,195,161,36,23,143,88,243,227,156,59,117,96,73,62,60,69,31,161,130,222,31,13,84,124,136,206,36,57,187,16,34,190,142,51,171,114,224,162,164,19,230,238,100,87,163,244,128,138,82,207,193,113,115,149,150,117,147,94,222,155,247,177,28,115,202,47,131,43,125,114,228,196,9,229,151,4,202,58,91,65,230,114,218,162,171,218,51,53,5,93,175,56,77,70,243,255,39,82,65,182,17,129,4,50,223,79,11,246,216,38,168,81,124,226,178,170,80,115,2,122,224,87,121,105,71,193,65,102,48,231,22,153,220,189,241,57,22,135,141,143,34,173,63,195,198,60,230,42,236,202,136,52,93,126,38,102,189,111,136,33,0,81,136,44,46,84,95,248,47,247,119,196,49,58,46,47,68,148,222,20,154,8,140,255,44,109,107,207,193,180,150,54,48,174,108,2,188,114,247,223,212,193,137,60,189,190,25,103,2,238,3,35,156,155,219,243,186,227,255,130,17,166,74,229,158,44,88,23,62,4,183,80,215,18,111,211,36,25,187,243,81,134,146,13,10,130,8,225,70,217,219,241,19,232,247,10,97,103,9,0,129,61,227,54,169,228,131,61,190,20,174,181,220,197,115,119,15,210,199,242,125,184,14,93,12,103,147,71,156,167,236,2,139,162,169,209,113,107,222,227,20,100,247,68,208,183,229,20,97,43,211,199,178,110,182,70,166,206,113,157,49,38,122,26,254,203,23,17,129,2,9,100,136,188,13,46,190,190,227,253,77,152,203,35,39,11,223,226,142,234,173,77,68,66,60,97,219,134,152,67,66,24,175,161,191,174,94,146,98,207,152,53,46,55,13,237,191,47,9,174,114,69,69,244,136,166,127,57,63,28,35,12,26,80,72,184,53,67,10,55,16,227,250,177,5,115,137,22,125,12,193,159,83,73,139,62,232,111,158,214,103,85,69,202,91,93,250,93,215,191,213,152,80,128,199,254,93,77,19,55,238,148,224,31,67,212,43,217,215,241,19,168,7,70,240,191,16,9,195,151,79,96,221,63,4,121,2,220,175,175,150,50,120,243,119,235,54,30,43,16,12,83,73,94,35,206,108,192,206,88,111,248,7,74,166,82,191,167,158,175,200,101,126,168,224,80,23,31,240,4,184,212,253,11,155,185,47,31,250,245,242,90,106,77,10,77,8,41,92,186,173,163,117,135,191,245,4,132,44,16,120,141,210,135,70,120,120,38,204,192,236,176,183,249,196,227,92,95,96,33,238,100,191,170,158,237,32,203,57,41,54,233,213,157,174,225,248,140,118,15,66,233,66,200,73,115,40,15,77,2,202,217,160,240,98,240,154,120,32,97,121,192,219,79,80,66,11,172,44,130,54,144,204,20,215,20,21,98,50,55,209,132,15,146,146,135,202,10,48,2,247,129,51,116,211,146,83,36,185,212,147,76,134,38,45,191,146,225,95,221,6,225,95,194,185,44,129,181,84,95,181,154,108,34,128,17,192,80,218,38,177,8,96,36,48,45,81,241,76,50,83,222,208,29,97,183,189,156,254,237,146,179,32,187,167,21,36,226,27,230,167,55,53,149,143,236,65,174,59,209,140,26,130,123,82,193,40,202,122,179,81,4,139,166,59,50,204,254,10,182,56,39,183,123,99,16,39,55,245,65,77,186,113,249,237,156,0,41,161,60,191,95,167,246,255,34,153,166,247,15,3,118,54,247,71,104,72,167,34,190,80,56,75,117,182,15,196,161,21,247,228,169,143,203,26,190,19,158,109,234,246,153,51,43,252,215,187,214,173,31,14,30,223,211,4,83,197,95,246,185,169,137,121,30,38,16,90,111,72,247,7,71,89,116,36,185,102,14,52,11,103,43,43,224,77,39,169,97,41,244,239,49,40,161,167,82,119,169,232,157,137,5,208,126,151,37,220,155,159,17,210,72,14,8,249,13,211,126,211,107,162,160,219,156,131,39,138,193,251,72,77,74,8,33,12,229,240,191,161,66,74,54,18,24,170,129,2,24,23,237,147,236,235,88,185,140,71,240,24,221,87,106,199,178,250,52,146,156,176,118,183,130,78,179,193,156,98,203,243,49,151,73,61,249,67,179,110,239,118,219,38,65,244,34,1,207,148,147,97,154,215,154,99,13,13,149,114,137,17,39,172,221,23,174,99,164,111,66,44,167,34,251,251,94,229,227,203,227,100,73,252,67,145,142,15,20,185,28,177,239,39,179,78,143,231,85,89,186,118,236,237,150,227,111,61,17,32,26,106,6,165,22,11,149,4,104,234,145,253,50,54,54,111,52,19,105,106,245,48,182,24,145,14,123,227,71,179,199,127,207,44,242,221,248,115,219,123,31,2,106,27,90,136,194,134,136,170,4,143,190,238,169,136,71,53,213,18,116,155,127,207,112,254,194,129,58,204,255,102,126,83,111,42,53,198,253,94,42,206,171,89,112,194,170,127,212,140,93,42,202,103,6,29,17,47,60,100,114,81,27,79,123,217,161,196,65,72,72,188,249,216,242,131,201,217,215,19,169,172,11,220,234,68,120,104,178,214,81,203,107,231,80,187,215,239,50,204,252,89,201,48,116,170,57,239,49,217,109,66,41,155,94,179,56,238,3,253,234,24,72,246,104,210,162,151,211,252,200,230,149,126,255,195,164,116,215,59,14,227,122,30,245,61,114,128,48,28,158,236,66,189,125,15,142,36,24,65,79,203,70,20,137,92,110,155,165,69,221,111,203,104,72,224,142,140,225,50,63,115,227,240,205,253,190,172,134,57,32,73,152,45,9,150,157,93,111,191,144,222,6,209,171,73,15,200,105,151,43,0,172,182,190,126,253,91,208,38,66,30,29,242,20,199,60,220,15,165,208,39,117,127,255,22,128,62,121,208,70,109,254,85,239,185,211,66,35,181,79,223,170,208,204,129,161,72,184,149,82,229,206,58,122,17,151,123,89,173,168,211,81,21,69,251,188,74,201,216,226,71,87,139,54,156,2,247,207,189,162,192,95,175,137,144,140,150,79,186,50,167,149,181,130,176,89,118,33,118,153,122,73,102,249,95,53,183,250,26,196,94,148,180,105,151,157,17,62,137,154,143,61,63,184,149,98,144,126,14,123,144,184,105,201,233,142,26,201,154,142,77,154,47,58,155,38,248,163,238,211,74,112,86,248,51,56,7,34,88,188,43,10,198,101,51,24,7,145,156,136,115,221,111,150,80,19,13,151,195,87,4,208,153,185,161,28,20,134,43,18,56,15,33,46,44,241,74,186,177,123,144,46,135,104,44,100,99,69,86,167,127,132,60,219,249,20,207,30,249,128,45,242,108,228,105,175,141,202,11,178,49,185,47,159,253,53,179,215,21,25,114,67,38,227,250,21,125,67,59,119,20,214,105,195,166,215,238,230,37,124,79,125,81,29,182,41,141,135,209,9,84,99,51,105,140,141,191,153,23,31,45,86,247,29,183,125,237,73,229,204,58,185,187,7,143,142,114,83,108,96,82,227,149,222,8,173,237,88,82,92,170,225,153,101,157,71,107,110,218,62,103,254,144,169,26,44,238,154,117,66,186,73,142,188,216,6,149,107,145,40,1,199,91,213,58,183,10,177,176,185,249,131,241,4,71,231,34,239,126,205,3,94,163,3,127,219,171,255,205,173,52,40,11,41,24,42,104,136,113,67,115,214,193,57,142,16,147,148,112,116,98,208,238,157,146,83,140,103,221,63,222,27,136,0,63,22,245,54,239,101,190,103,106,28,146,255,202,150,74,105,230,105,150,132,160,128,219,65,219,62,47,125,230,78,180,105,174,103,208,158,9,99,196,95,123,89,247,225,198,156,49,242,125,119,194,247,194,127,212,110,29,141,149,142,81,26,15,73,255,81,144,110,207,206,97,222,201,55,71,79,201,154,185,213,61,49,141,9,60,125,136,125,20,215,1,247,232,125,24,87,195,250,138,212,220,188,251,210,15,34,225,116,216,75,161,228,108,51,166,54,153,162,195,73,183,88,55,242,166,55,66,156,57,132,138,47,132,31,155,31,138,101,176,124,210,13,189,4,217,36,113,229,16,200,100,8,41,38,178,226,140,205,93,201,186,251,255,195,35,99,13,12,75,220,11,52,164,106,111,93,31,60,18,132,235,4,139,49,102,51,103,115,237,76,114,27,216,37,144,248,194,80,3,225,26,13,2,95,159,198,130,29,53,196,5,119,25,162,160,177,96,194,194,241,219,122,152,79,221,144,50,213,192,101,66,36,138,53,232,217,206,107,66,81,193,250,138,83,198,169,176,212,159,63,90,4,18,229,57,236,200,161,49,47,255,97,47,149,7,246,74,105,52,146,188,85,161,171,186,142,113,108,165,56,121,234,115,145,49,231,96,31,61,68,106,12,234,5,176,41,141,151,25,173,152,122,30,46,59,122,46,215,141,17,115,22,185,62,61,224,227,231,121,43,97,38,153,208,196,134,172,17,192,142,172,41,134,42,33,236,240,166,204,5,164,179,217,92,61,198,242,181,141,169,224,186,187,125,58,201,214,197,255,197,175,77,188,167,208,170,242,3,100,150,143,50,219,33,29,219,92,238,241,203,186,77,122,255,164,3,15,54,120,56,85,27,86,43,87,64,72,67,130,240,168,144,195,96,66,200,194,231,82,174,36,7,198,227,150,68,195,37,171,56,115,124,98,79,88,246,175,19,228,89,52,176,190,103,221,69,32,142,224,92,148,198,18,124,67,79,37,98,68,230,170,190,189,235,35,104,245,24,33,215,36,112,225,211,94,106,121,106,98,173,74,244,247,240,229,37,123,204,20,242,238,108,101,214,169,245,57,218,5,46,206,146,236,111,211,0,141,116,7,58,119,131,88,207,48,218,45,89,189,87,151,223,46,65,126,98,95,109,181,86,212,99,151,179,13,41,251,155,84,233,216,127,233,197,66,103,87,205,246,24,162,40,104,153,239,193,142,254,156,67,104,86,220,244,72,179,223,98,115,133,250,171,107,126,141,80,42,155,141,162,53,17,168,88,231,179,94,229,1,97,39,18,215,70,92,32,110,98,218,207,116,173,126,36,218,63,109,122,160,251,124,126,16,170,138,24,134,67,91,239,85,26,248,139,71,100,156,134,225,145,192,7,23,24,9,76,115,251,2,195,221,193,63,235,224,60,229,231,12,71,240,75,240,152,157,180,229,172,106,247,106,203,251,67,101,167,109,214,123,51,156,27,109,179,51,136,192,104,96,70,174,69,65,89,9,134,55,189,145,179,234,170,229,22,223,159,219,153,196,237,237,196,179,190,119,82,0,163,125,159,44,254,135,38,159,61,76,103,221,227,47,1,3,47,229,77,145,122,188,140,151,61,231,215,176,47,182,163,156,200,20,234,10,229,48,65,140,63,164,25,151,78,193,35,162,142,43,142,141,107,77,125,251,191,102,137,24,92,148,132,178,162,18,67,193,84,141,67,170,46,150,244,5,123,133,94,103,97,245,83,177,216,223,98,76,30,13,84,127,18,61,31,250,240,36,181,121,216,32,79,93,132,113,208,249,38,224,240,251,101,168,100,159,210,89,33,92,145,72,7,176,71,179,171,176,103,178,255,84,80,230,65,136,164,58,21,69,147,100,181,216,89,41,51,236,183,49,142,101,197,133,195,27,85,14,250,142,207,238,231,89,224,248,43,170,87,250,87,115,173,88,173,216,81,135,149,15,119,88,55,110,164,79,178,159,199,110,160,149,84,123,102,200,147,208,108,191,89,172,198,198,217,134,180,214,105,50,189,122,141,233,115,47,60,109,191,137,133,224,229,140,118,145,188,162,81,232,53,190,187,253,91,170,239,19,229,38,65,140,218,223,88,162,97,148,183,255,176,73,12,158,150,140,13,249,10,187,255,108,177,98,238,245,188,242,221,120,82,229,130,120,220,113,189,197,125,161,52,86,48,237,139,23,221,245,242,81,251,135,191,14,4,45,248,38,249,27,178,207,9,238,84,3,167,175,199,229,146,62,143,115,67,54,180,147,230,187,104,85,56,111,200,96,4,162,125,212,78,143,152,223,122,176,87,154,132,2,37,192,200,115,59,8,48,247,219,252,3,84,99,20,38,83,15,232,48,207,168,104,8,144,78,216,246,125,55,110,16,243,13,50,237,62,240,167,191,226,173,226,95,206,137,129,71,0,82,73,0,194,67,0,16,169,8,58,4,195,93,61,209,33,16,242,120,194,115,21,209,217,194,147,24,113,242,108,95,44,210,114,74,59,154,149,92,132,74,215,230,188,149,5,53,241,125,12,46,198,148,39,162,10,161,73,227,63,123,198,164,4,40,175,110,168,199,254,170,45,127,192,7,46,178,36,173,99,254,211,212,41,97,129,4,50,41,30,138,23,254,207,113,130,206,45,182,174,14,85,195,15,179,7,174,22,206,43,41,207,78,118,116,77,190,56,13,103,142,167,94,165,120,204,141,227,180,222,132,169,191,50,208,221,242,206,142,200,97,80,223,94,230,145,199,168,58,102,242,240,129,135,161,240,190,202,180,0,139,199,66,10,171,117,151,218,142,6,54,131,121,108,13,249,6,168,189,252,89,74,219,71,230,220,252,205,55,155,48,128,67,52,119,47,247,57,86,195,231,215,12,133,192,75,125,207,201,139,17,205,156,67,183,204,197,52,204,173,91,123,74,175,30,49,74,61,187,103,184,255,236,163,55,79,126,34,6,192,94,160,41,73,218,85,124,29,148,157,0,103,162,158,238,152,201,62,100,54,182,4,62,146,221,213,74,39,105,124,86,211,241,198,41,2,49,130,64,23,221,111,145,129,217,13,67,89,8,229,79,94,104,207,68,49,38,116,20,178,42,16,95,226,154,239,55,187,72,160,224,249,255,16,174,113,10,205,98,59,4,234,64,235,128,108,251,36,95,139,119,62,149,97,127,31,191,185,112,77,255,88,17,169,172,251,207,29,215,125,112,20,186,104,237,156,70,11,104,109,107,43,78,184,135,222,43,199,254,230,57,216,89,40,143,191,32,127,166,244,145,32,171,115,131,32,181,30,149,126,134,173,72,177,233,179,99,90,175,229,75,194,140,104,189,161,39,237,199,225,31,31,193,75,163,90,62,96,181,241,227,98,146,131,212,77,226,116,137,118,206,100,163,2,145,20,152,111,204,172,72,162,158,182,4,144,49,198,126,232,86,131,90,63,238,73,68,122,5,32,97,28,162,57,61,229,12,193,237,38,68,159,211,49,137,61,78,169,214,65,36,193,131,226,185,215,143,232,131,226,240,240,246,214,94,40,25,246,41,33,116,180,40,35,227,19,166,223,21,191,120,50,244,230,177,112,34,252,49,214,163,46,23,90,67,249,107,115,150,168,139,252,11,220,188,71,50,56,202,143,227,131,83,75,39,233,59,147,96,194,128,125,224,99,89,226,112,2,214,105,201,55,115,74,136,22,140,4,248,61,233,29,111,144,103,25,181,200,7,202,252,136,120,90,153,204,220,82,207,193,22,238,154,93,168,114,52,107,119,157,219,106,84,81,98,113,160,44,79,43,92,157,120,196,158,62,11,16,85,112,27,42,113,105,104,192,187,170,89,215,62,85,152,107,81,83,212,66,126,98,247,18,255,239,140,136,8,79,75,102,247,121,96,153,170,26,13,202,120,76,236,66,210,26,16,51,63,232,106,73,21,85,68,250,80,136,136,18,51,157,226,71,201,142,222,194,149,131,221,209,184,129,168,253,0,201,146,131,134,195,203,61,170,243,213,231,72,189,26,48,188,111,104,72,187,225,183,138,213,89,208,117,70,178,252,28,114,223,201,108,205,213,1,129,131,124,254,137,238,238,134,155,33,225,184,242,106,156,76,23,13,219,0,225,186,153,75,100,29,90,58,24,29,238,158,114,207,118,58,96,41,52,93,25,222,230,155,183,86,140,80,70,40,33,136,35,165,175,20,175,4,161,33,108,74,15,99,14,162,9,57,89,79,58,147,92,102,74,66,48,33,206,25,224,130,138,0,151,225,102,13,198,168,150,38,57,112,81,206,9,235,102,84,88,45,199,79,242,162,212,59,132,177,234,42,17,76,116,78,144,211,192,102,206,209,216,193,225,192,92,78,219,128,55,81,254,32,205,226,105,226,62,158,196,63,33,120,147,218,3,179,103,4,206,216,22,8,34,157,108,218,230,248,210,172,89,175,121,111,6,102,73,240,190,37,70,3,125,209,176,232,145,89,170,183,40,93,1,217,110,124,34,39,246,222,100,38,108,164,245,166,117,13,204,197,72,81,83,114,142,240,194,232,35,201,143,20,115,146,157,14,247,88,30,9,155,26,215,207,162,53,143,65,21,21,190,56,247,33,96,253,150,31,72,210,27,128,184,120,36,16,23,85,91,157,109,215,210,126,154,6,171,198,124,56,160,22,3,243,203,200,175,23,92,85,241,247,46,162,207,238,216,224,116,112,38,248,51,248,209,167,73,127,98,79,174,34,170,159,192,65,196,89,180,201,124,132,176,23,218,244,26,62,11,130,144,253,172,246,110,237,132,82,152,152,33,242,212,17,124,76,205,28,77,175,205,23,251,108,79,213,209,15,122,190,125,188,167,130,207,182,46,0,81,236,81,136,101,93,108,90,20,48,5,224,19,202,113,248,233,227,255,56,120,159,194,74,191,166,255,167,200,65,170,138,82,232,121,170,3,106,138,163,120,40,97,19,177,139,91,19,223,108,129,119,167,108,87,253,173,254,240,210,143,33,222,207,251,75,236,126,205,167,137,188,181,23,84,64,54,2,58,216,233,41,68,227,95,96,13,145,192,92,148,247,251,229,176,48,231,86,242,84,12,218,35,140,170,49,172,217,52,186,216,204,20,49,38,171,95,64,141,223,31,238,68,9,71,222,119,139,69,180,110,154,154,236,222,62,14,63,77,131,21,35,66,87,227,225,65,31,45,165,70,84,117,82,189,9,221,93,191,0,173,128,137,246,131,112,176,69,4,80,14,24,88,130,135,248,184,63,218,162,11,35,124,43,3,91,122,201,68,133,251,73,103,113,202,82,167,57,30,129,239,60,136,136,71,64,188,97,113,178,74,0,239,143,69,36,223,39,46,51,171,24,196,239,5,184,189,22,251,251,7,218,238,188,191,172,127,132,43,130,84,65,203,203,72,183,159,24,34,27,28,94,131,24,181,3,20,181,9,9,228,177,149,0,179,94,108,255,120,109,40,35,74,50,222,45,163,165,158,164,5,190,215,209,81,190,199,90,246,253,213,100,82,229,194,130,43,101,127,76,55,11,120,29,235,28,125,127,150,109,223,97,78,253,179,195,53,7,85,131,219,208,199,109,148,160,144,32,183,148,62,98,23,173,201,23,215,9,47,204,182,154,171,142,225,124,175,32,26,195,211,60,212,192,140,222,139,174,61,49,175,69,84,61,242,187,5,180,131,166,128,151,111,127,157,108,161,158,47,219,228,31,96,62,136,163,12,231,62,240,16,95,89,60,25,128,61,171,76,0,216,203,33,96,159,249,74,43,246,64,228,142,175,110,234,202,255,130,212,66,104,35,12,247,198,228,76,146,109,8,17,112,162,212,225,126,141,3,77,118,53,82,140,51,176,62,65,23,93,5,14,143,91,200,105,163,144,13,90,155,125,211,57,164,247,149,215,184,39,68,160,246,85,223,50,157,59,220,49,71,179,202,128,139,190,53,83,235,78,154,89,226,23,228,125,54,40,196,151,39,227,229,8,253,189,118,165,122,32,156,86,148,209,196,53,73,183,179,50,113,216,197,129,199,53,131,239,209,183,138,0,196,172,55,154,64,112,97,253,44,255,85,202,193,162,189,96,65,72,171,135,42,111,198,171,77,67,44,146,100,250,178,178,241,161,12,195,163,59,50,115,243,64,244,40,157,69,240,33,37,40,215,101,227,200,155,218,48,253,0,107,168,10,122,225,4,123,209,94,121,248,250,85,21,181,252,28,11,70,175,176,115,100,40,178,194,163,80,73,211,4,152,188,9,36,182,183,34,24,120,152,198,110,88,132,8,117,76,248,7,231,208,182,104,225,41,94,5,223,139,171,240,33,157,210,37,133,247,219,18,191,111,182,83,97,218,153,36,65,14,115,109,42,194,253,37,108,162,103,101,224,8,109,85,125,102,54,198,19,96,166,167,77,82,144,35,154,74,32,95,145,189,7,9,1,255,226,216,72,21,149,168,115,106,31,247,66,26,222,236,59,63,252,68,175,93,183,252,246,51,207,37,101,65,238,103,201,198,31,215,7,178,127,44,249,59,92,36,21,180,177,108,95,113,54,224,222,72,165,251,109,107,16,181,255,149,58,5,205,231,136,78,238,27,60,52,194,156,138,55,173,45,171,199,45,229,61,30,43,77,179,196,156,233,7,119,254,207,81,156,130,61,24,245,182,91,228,112,105,176,114,93,150,200,82,231,94,20,237,22,158,63,63,227,118,138,210,44,52,89,37,118,167,181,128,179,115,78,132,62,101,180,135,184,105,138,232,82,126,57,64,166,217,160,121,33,67,173,105,150,8,19,198,130,231,253,21,180,36,149,21,44,153,125,210,136,3,74,153,12,195,153,141,158,193,233,224,125,167,52,194,40,145,191,203,29,231,197,173,4,39,241,199,184,201,225,29,67,72,76,187,82,158,176,146,119,215,185,102,250,224,128,232,203,20,193,187,126,9,164,103,168,91,4,102,103,107,184,75,235,112,166,123,181,69,116,63,118,35,0,8,252,195,61,166,33,175,121,170,48,119,203,55,146,120,188,50,255,153,246,95,247,154,236,97,210,241,158,22,140,95,229,184,217,175,215,137,67,103,236,60,38,242,239,202,91,157,6,101,25,52,60,197,76,249,108,207,127,205,46,196,114,57,213,209,172,185,199,56,216,216,34,25,14,217,121,40,36,71,104,71,246,90,239,4,169,129,24,63,41,83,55,164,243,130,182,9,130,52,168,61,197,236,178,199,123,196,237,227,128,98,224,136,87,213,223,114,38,39,2,221,225,59,111,220,252,101,182,184,241,56,203,158,58,118,198,45,81,255,36,132,39,74,94,74,238,209,236,153,188,87,90,160,89,48,121,129,10,137,91,215,216,52,89,16,208,97,165,37,219,204,153,73,4,41,214,20,50,198,114,192,143,180,240,40,72,8,3,44,237,209,240,5,44,186,136,32,78,55,52,0,228,193,143,48,147,1,51,145,51,39,77,192,37,142,25,227,84,96,220,243,253,67,170,58,199,104,110,115,23,73,138,235,31,22,0,121,132,166,15,239,222,147,107,81,58,36,85,226,177,250,88,117,59,191,150,102,129,104,230,247,22,221,104,223,39,57,210,11,241,229,113,10,254,100,18,223,73,31,51,133,20,64,198,190,235,115,209,113,7,165,89,137,33,134,125,61,16,132,119,71,67,36,107,213,67,32,82,236,109,202,112,75,226,144,130,114,135,230,21,239,115,254,134,243,2,117,129,198,6,206,8,78,37,92,15,51,189,72,93,134,178,80,138,33,171,153,222,106,123,66,166,242,174,55,42,98,100,101,24,238,77,120,36,112,0,53,197,7,107,109,173,168,44,239,138,181,54,55,112,249,1,38,112,16,180,173,121,207,197,23,118,161,105,99,185,103,178,64,115,133,182,96,178,67,246,36,77,169,77,6,38,11,195,4,119,190,206,134,178,4,226,33,82,17,143,121,226,17,68,135,202,112,235,154,36,71,193,159,64,160,33,108,3,218,169,236,187,115,111,145,30,80,177,230,35,84,18,241,125,210,27,28,49,223,108,22,164,145,39,137,68,184,37,164,32,50,122,125,38,61,143,2,1,135,186,103,179,190,127,99,224,68,145,64,59,12,162,143,97,253,48,121,65,247,155,227,137,31,56,158,195,49,169,125,155,133,110,114,69,208,6,87,204,123,242,216,219,62,135,106,96,144,150,192,44,49,221,144,152,43,211,174,209,207,189,118,37,212,19,185,220,100,105,119,59,236,206,92,194,232,3,121,157,122,70,150,48,173,240,94,179,197,204,199,35,181,15,103,53,160,222,152,121,206,28,254,212,241,240,248,221,226,110,151,0,106,77,44,136,144,189,111,39,51,79,65,205,214,89,73,69,206,16,147,11,246,232,239,213,7,151,91,216,5,174,251,199,63,238,250,28,231,195,39,53,106,2,108,23,117,186,191,70,151,250,79,90,68,254,41,211,54,16,34,29,185,158,248,211,131,225,51,222,77,206,153,228,51,76,26,18,196,46,141,144,213,9,37,188,83,164,53,129,182,155,207,45,203,31,249,71,140,59,55,15,87,182,225,243,144,72,235,65,157,208,21,43,72,154,124,250,199,142,7,239,226,100,28,203,136,175,8,48,3,185,199,242,233,252,213,221,195,50,82,232,121,195,45,52,183,2,36,65,157,55,213,46,190,191,194,195,79,29,115,191,93,193,74,79,24,222,245,91,23,43,171,74,5,102,68,116,9,55,216,27,90,181,58,29,85,125,174,92,179,169,231,159,181,178,198,62,235,134,170,16,89,196,218,106,102,62,166,16,90,101,203,248,178,46,188,16,22,110,58,212,135,242,28,246,140,111,109,76,165,174,235,146,101,158,248,110,203,235,199,22,23,205,224,45,216,139,109,237,235,1,234,76,136,2,52,60,152,254,70,22,49,232,175,122,127,130,196,79,255,215,54,139,13,254,184,32,205,33,228,223,186,189,167,212,130,224,68,220,33,13,4,53,1,126,214,14,208,164,179,250,80,128,192,142,106,194,115,179,226,166,89,223,120,74,108,62,100,198,65,120,224,210,203,35,48,193,94,201,221,185,157,110,182,218,149,238,39,238,13,84,144,12,108,37,188,250,205,21,185,163,131,52,11,114,17,230,200,95,63,11,222,254,193,147,206,151,10,82,232,121,165,88,77,156,215,11,248,94,29,165,107,237,181,59,252,173,184,223,187,179,132,92,126,36,61,207,8,137,247,98,55,168,233,244,88,109,90,8,240,219,169,111,120,223,71,192,66,211,246,118,251,221,199,76,231,247,156,51,95,2,145,94,225,191,113,6,203,208,111,41,110,251,219,12,132,224,148,106,123,197,130,166,223,101,242,158,68,240,86,17,105,144,204,20,93,180,167,9,165,106,150,65,68,247,111,187,37,183,123,251,228,127,231,196,193,21,82,247,172,247,159,151,223,235,39,60,56,54,166,238,63,37,86,254,5,232,19,22,215,111,166,135,99,99,189,168,76,69,116,77,214,193,42,55,241,69,111,58,52,190,110,3,77,138,161,61,157,147,220,5,217,119,143,190,143,97,207,227,171,137,207,173,196,92,19,93,94,46,205,147,186,105,79,250,20,126,208,211,238,227,187,209,211,55,46,170,212,154,140,63,161,95,108,119,225,87,192,167,83,238,157,146,131,110,125,216,51,103,138,68,98,251,3,102,21,148,72,42,104,70,194,246,238,191,70,2,59,7,155,121,150,206,239,27,15,143,21,175,23,87,231,90,197,139,9,224,52,193,76,106,85,122,11,36,13,252,75,142,106,232,158,91,36,75,246,26,68,7,16,18,184,246,237,83,225,201,87,37,23,252,215,207,23,168,199,206,56,77,126,197,192,144,149,190,122,53,219,144,122,211,87,228,59,43,62,15,120,35,209,82,114,144,118,234,102,31,210,33,41,41,191,128,118,75,113,198,120,19,156,89,132,80,70,228,26,108,87,108,140,180,37,0,216,60,20,234,47,184,130,18,239,243,136,83,238,213,11,248,61,19,115,169,54,105,54,77,54,115,152,124,19,69,64,80,125,177,50,102,56,153,71,207,77,8,180,241,65,203,181,208,51,62,160,78,133,253,80,131,61,223,155,152,232,238,64,213,192,90,106,61,185,222,164,146,79,255,112,204,154,40,183,146,30,80,113,141,66,32,191,37,196,54,30,161,202,93,176,217,248,232,179,33,51,216,196,227,94,89,19,224,96,107,96,75,97,240,202,171,166,168,188,121,138,80,254,82,149,4,218,248,61,252,79,6,227,23,240,0,45,48,210,125,44,253,71,65,141,184,52,181,190,9,40,62,235,197,115,14,208,81,214,12,228,10,164,126,169,205,64,160,122,140,234,225,21,213,231,4,180,150,126,242,52,14,57,108,67,137,29,238,41,156,143,71,71,12,201,131,92,74,87,27,136,123,175,26,220,134,137,224,44,239,162,198,159,102,246,175,95,249,97,206,197,213,61,93,204,83,135,46,187,96,191,218,253,189,245,209,32,244,151,185,231,114,142,135,211,225,176,79,130,33,146,123,111,30,84,109,193,4,18,103,250,114,251,245,166,201,100,74,5,103,150,75,203,15,181,79,132,45,186,48,93,24,133,64,210,61,202,11,122,4,195,30,38,61,61,2,243,189,44,60,13,198,245,22,147,28,111,16,41,5,37,53,101,23,200,173,221,139,47,191,98,43,167,61,49,37,125,112,72,86,55,85,205,3,127,116,181,123,193,118,70,204,182,117,237,28,110,32,195,247,73,178,114,188,193,177,83,52,210,111,177,153,89,77,82,255,68,57,223,74,245,215,185,212,95,230,173,9,5,37,25,175,5,165,106,230,98,152,222,249,189,87,47,53,240,152,227,238,138,193,247,104,236,250,214,153,39,29,126,49,143,102,148,87,178,47,124,245,211,206,224,144,51,250,233,237,52,127,57,136,223,242,86,170,32,240,178,109,200,234,185,225,88,80,154,41,249,198,91,230,241,144,45,130,5,86,209,176,240,167,89,145,44,7,37,157,2,44,147,227,159,81,206,103,46,169,4,232,187,137,54,184,110,130,217,45,93,78,99,187,141,1,47,247,129,207,50,127,250,43,220,134,223,138,149,174,152,127,85,123,39,227,72,143,54,108,43,244,247,251,49,67,249,8,96,179,17,54,231,103,236,10,104,26,148,196,146,46,42,216,51,25,143,176,34,18,8,2,38,184,14,33,228,173,165,62,72,195,106,207,160,215,147,197,188,164,218,23,143,19,101,73,181,103,162,60,1,84,125,17,224,99,66,1,31,184,223,50,23,137,241,126,29,102,138,129,189,124,89,196,140,41,124,249,237,82,141,89,104,189,224,64,178,171,4,24,237,228,217,251,201,8,250,143,133,191,119,160,208,215,15,229,127,253,90,207,155,31,95,232,244,85,220,202,221,124,128,47,116,97,206,193,210,82,44,59,192,98,61,249,201,182,195,216,176,207,221,162,186,193,81,172,65,195,82,98,159,223,45,131,104,7,181,209,165,3,115,236,11,30,165,184,9,162,113,237,108,205,79,184,25,94,1,160,157,62,97,2,142,94,145,216,190,216,33,97,194,169,64,22,115,131,99,72,82,193,1,247,199,61,162,101,16,213,77,49,81,182,234,28,9,60,158,36,141,124,88,137,128,140,147,9,88,92,249,213,113,139,187,122,162,106,141,41,119,6,241,5,248,0,238,195,193,45,21,50,86,192,158,130,201,150,63,57,149,2,16,239,119,132,129,233,31,244,84,7,94,8,59,201,160,64,8,37,16,200,27,41,1,168,186,108,192,142,140,145,45,220,224,221,229,155,106,128,231,80,251,151,107,20,232,18,19,98,233,153,238,25,255,206,236,203,165,134,139,88,240,143,250,152,134,106,34,221,73,51,61,109,139,123,250,11,186,223,197,239,60,124,80,190,5,127,68,225,225,28,110,150,152,29,174,248,125,203,202,249,110,128,232,140,55,214,26,178,66,38,194,172,139,140,181,162,180,188,161,210,120,238,157,167,57,159,214,192,175,95,163,190,22,160,31,55,197,46,228,126,154,163,77,193,187,162,48,67,97,52,205,72,60,166,8,215,55,10,131,19,125,139,94,103,66,21,38,40,70,155,189,32,199,187,103,91,122,98,143,228,231,226,10,175,66,37,67,232,172,201,141,122,13,105,163,24,227,183,53,239,39,136,20,126,48,206,232,54,51,166,48,220,19,22,119,5,162,157,109,226,24,237,43,118,14,51,13,222,17,11,16,248,77,119,76,119,80,242,51,223,245,72,4,81,211,195,9,91,232,206,5,76,101,202,233,239,14,22,121,159,141,51,178,204,159,209,223,109,17,208,223,177,221,29,108,184,233,147,236,50,108,210,104,125,158,161,72,176,116,198,78,124,249,44,141,117,211,100,211,68,119,172,67,195,66,33,195,115,245,160,79,9,44,125,176,89,231,74,250,114,102,86,220,212,239,196,45,22,193,157,189,125,166,242,198,35,123,251,243,56,246,252,216,158,225,12,157,118,93,61,149,238,68,61,31,189,244,76,68,241,14,185,3,178,2,128,159,159,85,27,96,179,167,139,134,22,180,16,24,72,32,83,187,193,169,63,233,228,183,215,137,207,24,116,181,144,77,178,218,157,89,237,215,108,90,51,92,53,206,183,122,96,26,237,185,182,24,116,141,236,80,29,122,190,227,147,25,188,157,164,233,239,140,64,249,132,170,222,151,199,253,75,24,71,6,233,64,44,123,135,1,117,80,58,17,182,244,221,10,44,142,107,73,241,170,6,250,148,216,118,111,46,226,125,195,220,229,239,247,176,154,255,11,175,32,204,211,69,31,217,64,64,16,48,81,57,137,59,88,52,10,168,184,147,235,219,213,205,169,123,65,82,81,197,121,153,63,47,149,165,239,99,176,150,180,56,130,136,71,208,33,100,225,225,176,184,168,115,73,141,44,9,187,19,202,227,158,25,87,89,82,229,153,56,75,124,2,121,197,240,195,67,180,53,121,117,43,44,255,68,61,231,188,244,188,40,144,147,242,205,167,177,242,226,134,49,138,87,159,52,133,231,150,109,142,148,8,92,252,229,183,204,179,229,126,239,218,184,243,241,2,113,220,56,132,242,3,146,3,212,172,232,78,165,17,207,162,159,138,216,172,5,236,18,29,8,123,148,84,53,243,117,184,125,36,30,253,108,39,218,222,214,21,112,120,133,179,52,89,51,125,79,15,236,70,198,46,49,237,34,115,51,133,216,126,181,25,133,236,12,76,71,184,138,243,163,185,30,251,206,139,48,69,84,101,129,137,249,160,199,85,239,36,163,89,228,141,50,67,231,50,34,220,41,193,7,132,250,127,5,239,121,224,100,120,202,61,250,8,69,14,0,109,193,100,64,6,214,115,137,156,65,2,137,160,135,247,121,117,240,190,132,104,98,132,161,46,247,118,160,203,237,211,27,14,34,208,114,162,62,201,194,245,77,233,16,186,112,193,23,196,103,29,92,78,176,141,11,219,104,86,17,216,227,130,204,158,59,16,247,61,165,34,192,69,248,195,149,95,85,234,89,56,169,78,127,4,86,26,194,155,171,168,97,200,113,255,253,175,121,226,88,214,183,3,140,218,73,245,101,197,3,17,96,102,131,102,67,16,253,39,190,135,171,81,192,130,164,130,166,62,113,247,10,178,230,99,110,62,157,13,252,25,191,114,62,47,225,123,27,30,110,170,5,121,171,235,25,189,65,96,62,36,182,221,127,149,210,64,113,242,100,209,123,139,249,179,129,62,166,29,69,255,28,161,32,181,61,6,242,97,78,93,239,69,149,182,31,17,77,18,247,98,221,146,159,79,228,211,37,142,134,198,78,137,74,174,74,198,46,243,120,122,35,201,241,143,22,187,224,23,209,65,13,255,71,197,91,248,69,21,110,223,195,2,34,37,93,10,194,144,130,128,132,162,52,67,135,32,41,34,2,34,37,8,72,119,141,72,143,72,151,34,12,161,164,52,210,48,74,135,116,119,75,199,12,53,3,51,231,188,31,245,222,251,251,190,159,243,15,192,60,251,89,123,173,181,215,126,26,91,173,249,113,156,148,137,200,119,87,2,226,142,203,190,0,124,248,181,209,101,127,227,255,20,130,50,78,11,103,136,51,5,34,113,229,235,129,86,156,96,146,183,62,80,39,51,46,204,4,135,62,113,192,217,250,250,142,47,158,210,170,166,251,199,106,230,58,55,231,21,250,244,12,126,254,25,197,117,102,219,231,182,2,70,104,171,51,90,171,11,197,64,58,199,61,50,76,143,94,228,158,106,48,88,242,232,155,30,187,235,178,148,58,60,95,45,253,71,116,11,109,174,38,211,20,175,55,221,167,68,154,250,44,197,203,29,173,59,122,75,228,135,203,200,75,238,229,87,9,109,88,105,49,13,84,155,182,86,117,30,52,190,105,42,53,93,88,238,189,181,30,155,203,22,122,228,236,210,190,117,49,180,233,32,108,123,53,41,162,126,61,44,55,161,78,249,46,104,77,66,116,161,207,188,9,79,214,125,132,23,13,9,131,201,178,133,222,108,108,61,242,137,142,199,21,129,13,141,164,153,43,14,145,37,13,26,224,21,50,135,69,76,50,48,224,170,160,97,166,99,3,179,129,141,72,116,252,103,82,190,112,251,136,27,234,126,27,228,62,118,250,67,252,54,96,202,247,249,1,189,74,84,154,37,79,24,85,203,146,157,122,172,251,172,148,54,212,135,33,154,171,185,196,30,243,75,106,106,123,5,172,79,244,49,85,223,63,56,72,56,124,105,180,117,249,233,19,203,220,60,124,251,247,164,152,98,199,235,77,150,192,6,119,44,93,73,49,57,140,156,239,201,95,178,171,125,231,207,17,223,193,221,95,91,181,94,163,63,27,127,239,98,45,62,28,28,128,50,138,185,230,222,158,78,24,41,30,43,234,63,247,176,172,178,233,200,57,155,181,124,233,229,247,7,233,81,239,243,220,244,112,219,20,53,231,175,90,7,168,15,20,123,107,71,235,220,38,239,161,59,204,155,169,124,140,220,90,72,39,115,35,192,155,243,234,114,186,123,187,133,130,129,158,236,69,187,244,153,132,18,43,136,141,168,108,73,241,68,232,41,146,230,106,26,201,54,100,123,105,180,157,168,10,250,36,169,10,249,132,114,21,194,203,190,210,69,159,253,111,28,145,164,213,7,198,131,196,230,87,50,249,193,177,82,34,153,112,156,75,39,100,190,174,207,45,99,155,1,38,25,224,221,65,197,38,245,74,93,116,193,204,120,40,219,203,227,162,161,149,64,230,129,236,42,126,126,65,213,219,59,25,231,170,71,165,139,242,185,232,145,154,7,159,55,231,217,43,107,197,112,173,38,123,148,250,194,188,231,26,253,77,23,106,180,163,185,212,117,33,74,10,164,102,143,255,52,253,79,246,67,21,142,108,59,178,206,75,11,30,63,14,186,163,178,115,232,237,228,8,232,187,226,161,158,163,44,169,66,21,153,50,181,86,226,122,36,191,141,205,9,151,72,59,210,83,19,108,248,185,28,20,19,45,121,67,133,242,18,249,142,30,94,175,214,86,105,154,159,78,147,149,160,104,215,7,154,111,78,142,185,189,120,127,55,107,78,211,174,6,222,190,156,254,55,16,17,169,19,66,213,38,191,186,206,64,241,71,191,26,231,0,4,51,217,177,169,127,141,10,202,131,248,100,91,167,120,179,236,168,191,61,206,253,75,36,198,167,42,163,140,113,29,214,3,62,58,11,17,135,63,12,253,77,228,136,134,110,128,130,192,79,157,132,139,171,79,229,14,238,43,227,134,18,18,244,3,88,15,249,119,218,100,224,152,110,149,17,218,24,254,213,166,247,228,50,219,103,116,59,87,160,159,157,153,188,148,87,96,244,204,201,179,59,82,127,90,222,144,219,172,84,107,65,143,58,227,3,46,253,154,142,226,146,237,180,127,115,26,97,232,31,246,27,172,109,119,114,83,125,240,195,204,218,16,210,246,124,117,65,33,128,218,59,60,135,66,70,109,208,209,72,244,213,212,27,83,59,159,249,192,15,65,27,239,75,159,134,51,31,73,17,92,17,64,201,138,201,183,4,85,69,4,95,139,96,114,215,204,31,211,36,154,181,65,255,88,83,188,117,239,103,151,131,116,132,160,172,116,93,103,34,239,205,41,82,231,174,25,175,32,43,110,28,47,108,81,209,140,105,218,133,171,166,87,154,233,20,122,200,59,10,125,82,159,163,158,228,254,239,87,80,181,251,1,67,81,71,254,220,15,199,48,51,218,76,166,212,176,207,11,37,191,170,20,6,182,83,141,112,75,170,220,21,217,243,81,176,94,80,107,246,29,60,244,211,213,113,138,7,171,22,57,50,20,70,2,0,47,208,25,76,80,169,192,71,86,185,76,62,85,241,43,232,154,105,138,13,76,125,48,171,206,71,44,183,144,213,112,136,109,101,220,67,238,217,234,225,248,145,148,167,91,143,231,35,170,206,169,205,135,77,242,51,239,150,222,44,13,65,204,66,109,134,35,78,111,232,135,141,168,104,51,137,233,143,183,150,253,132,212,254,182,231,254,71,12,54,21,21,200,114,134,66,23,133,164,207,6,148,131,188,135,214,46,247,115,14,217,126,220,42,222,108,191,182,118,126,105,168,43,106,246,248,131,150,211,212,128,233,254,160,105,173,169,50,62,151,240,166,132,67,141,171,184,11,182,136,244,91,211,131,238,119,188,103,232,251,15,13,28,107,219,228,157,42,165,152,124,95,220,28,171,214,182,26,156,145,74,15,143,181,251,93,54,154,196,52,189,206,12,239,106,93,49,166,116,255,144,218,24,220,6,239,33,238,137,53,248,55,89,167,10,12,135,14,255,1,11,197,235,255,248,208,255,141,208,244,128,137,224,29,80,38,238,196,21,52,65,145,116,90,200,42,110,140,254,40,28,227,235,66,168,169,13,90,239,72,197,240,183,213,120,100,182,96,214,78,60,90,240,222,171,235,38,113,214,35,173,174,159,156,187,32,55,146,163,137,7,163,82,2,201,186,150,28,36,115,11,109,195,191,127,43,213,213,204,77,143,112,102,84,99,184,163,207,112,174,136,248,35,6,164,9,31,145,6,73,171,85,215,118,190,110,150,61,76,40,160,158,173,131,44,56,186,64,164,153,170,73,71,110,16,208,178,20,176,52,83,108,93,56,154,58,73,44,82,158,124,117,156,84,119,39,77,117,112,119,39,124,115,20,167,118,125,242,253,238,103,193,84,199,235,133,150,237,183,43,14,185,85,224,26,151,189,216,132,73,252,163,103,118,6,119,140,187,239,60,187,121,186,152,26,145,56,53,254,255,250,61,243,111,197,51,146,87,134,255,63,168,23,193,34,208,72,70,152,30,238,171,193,154,46,55,183,245,217,11,187,230,188,63,167,234,101,101,163,239,115,158,77,153,245,42,151,63,188,199,224,215,251,198,95,237,86,49,229,27,55,76,208,126,197,162,246,133,65,230,73,111,126,216,231,78,202,158,222,74,117,124,42,100,148,27,133,249,83,239,174,4,127,170,253,74,228,195,168,31,173,18,141,123,173,221,212,211,237,67,205,150,121,121,214,9,137,57,19,154,17,175,6,118,252,47,89,22,41,61,187,75,77,223,160,114,137,231,127,182,87,188,28,141,208,85,249,242,73,202,232,25,66,225,193,206,76,199,93,102,159,42,182,185,77,14,213,39,40,134,6,87,254,187,237,23,70,178,226,144,12,99,220,179,44,194,238,227,249,198,224,31,183,255,151,133,176,164,181,249,223,169,133,114,37,9,24,222,135,195,250,65,215,58,77,192,152,39,58,79,43,140,158,17,241,7,214,5,129,108,140,22,111,39,66,109,240,195,236,165,250,133,216,167,194,165,198,120,142,157,182,196,60,184,206,103,150,174,111,82,150,179,30,146,49,25,129,92,25,254,66,171,46,223,162,159,153,48,6,51,20,100,172,157,120,148,58,98,179,114,211,253,157,7,224,182,79,141,75,138,54,73,51,225,52,233,31,72,249,57,197,89,15,47,186,113,191,233,11,212,246,66,248,168,167,229,124,37,134,3,204,137,156,101,100,87,8,185,219,108,223,188,41,221,199,24,176,38,42,204,149,90,123,84,147,204,87,193,62,238,197,136,220,248,192,219,155,143,45,106,83,223,238,53,171,81,115,141,80,43,22,125,172,125,52,108,159,83,186,233,239,203,83,187,80,159,115,175,110,61,113,115,61,113,236,97,39,75,154,236,176,96,224,246,92,99,171,181,234,179,48,104,7,87,47,145,65,210,244,159,106,181,45,37,116,251,23,114,115,147,17,184,100,181,81,250,123,158,247,37,189,106,147,255,229,6,122,193,100,176,20,19,186,42,146,194,12,147,246,1,154,217,14,100,157,51,23,136,178,120,164,71,223,159,51,88,6,109,117,188,142,75,195,74,252,86,230,144,2,66,140,194,84,245,184,76,58,234,111,98,161,73,22,251,187,9,28,14,93,50,112,209,196,194,210,134,159,15,57,76,106,94,109,24,240,192,29,124,223,194,105,104,8,239,223,32,224,13,123,117,52,208,146,142,56,11,197,171,239,177,107,147,213,109,94,186,204,97,110,168,29,47,115,116,244,204,43,29,245,190,75,157,248,80,27,96,23,185,63,91,57,195,244,171,188,61,86,64,156,244,185,66,232,170,46,235,133,24,135,150,168,180,155,144,160,47,21,206,15,85,221,200,8,127,189,160,183,109,84,36,79,252,202,227,82,118,63,3,241,77,146,68,183,131,242,239,186,15,156,74,45,55,242,30,201,245,255,20,110,38,231,199,20,39,93,56,249,237,72,145,10,253,42,104,153,186,13,172,72,65,89,219,44,141,235,36,229,243,102,226,117,253,254,255,142,217,255,124,183,73,140,113,25,17,250,255,170,155,25,195,20,45,236,127,168,17,220,101,116,6,149,108,26,10,208,96,240,58,93,142,211,204,205,34,144,121,119,103,235,90,100,68,102,31,218,114,230,151,139,33,195,79,137,246,200,24,27,90,193,98,189,159,231,244,110,42,180,5,217,214,185,133,108,187,159,253,157,157,51,233,84,131,223,159,114,94,125,117,133,240,17,233,192,219,12,223,34,232,202,244,143,215,151,131,236,177,215,102,93,212,161,146,180,220,111,178,177,244,117,223,177,199,59,123,169,172,15,103,205,235,94,56,178,62,79,139,28,112,205,72,205,98,180,105,199,28,234,50,97,214,174,21,13,10,214,199,213,118,149,94,151,31,149,150,240,216,43,154,142,11,146,98,10,117,137,111,213,186,80,149,36,32,90,104,174,129,101,231,212,141,156,134,67,109,133,122,13,57,157,26,222,93,242,192,118,96,201,36,143,162,79,226,250,149,70,228,250,46,35,79,202,247,116,61,19,42,74,247,238,53,244,252,141,23,72,157,158,80,163,134,134,105,87,151,86,151,214,105,42,232,79,54,201,171,50,5,235,117,113,166,184,12,52,7,112,23,84,6,140,85,177,22,155,221,221,123,71,150,49,252,59,172,29,133,92,205,136,45,254,84,13,134,83,234,204,8,249,205,1,165,114,213,165,211,200,205,119,120,158,139,118,146,175,163,207,244,167,80,244,147,239,70,84,246,7,180,153,74,43,158,54,151,20,178,113,191,255,100,124,215,48,55,170,88,87,149,84,251,254,213,100,154,79,175,36,246,170,131,23,80,40,178,128,131,148,243,61,121,109,178,243,147,254,195,217,14,201,148,224,103,14,186,13,10,63,93,94,155,110,24,182,45,248,183,191,42,81,253,189,132,53,179,100,115,181,173,213,189,42,114,63,88,222,86,47,28,6,168,220,61,239,84,68,61,120,109,22,72,55,121,82,90,157,179,146,143,32,135,120,10,143,61,192,157,20,189,14,190,38,114,40,56,187,123,193,252,146,239,127,119,189,215,170,7,224,161,120,84,45,112,41,8,132,80,41,150,117,190,179,13,198,228,47,27,174,90,16,139,174,34,132,121,1,78,32,211,252,99,149,14,55,72,82,149,112,66,86,249,246,224,191,114,133,26,11,25,91,2,37,97,236,209,185,194,205,8,210,94,206,88,158,157,174,40,46,93,6,202,85,54,213,116,245,180,56,235,36,133,209,82,126,171,200,10,162,207,218,73,41,128,164,68,109,73,113,177,19,222,33,134,171,77,35,247,97,172,128,67,87,19,188,162,213,217,168,101,32,163,132,86,149,55,245,235,3,78,61,19,82,126,206,39,38,231,107,85,48,86,42,70,188,176,26,209,194,101,7,193,110,119,79,54,191,222,226,245,207,138,149,34,38,178,75,222,92,4,158,155,101,84,54,103,172,205,236,74,4,225,135,59,208,7,186,115,246,16,125,226,29,152,4,81,43,98,19,61,41,206,80,153,58,24,186,32,126,163,240,156,121,238,107,59,158,227,169,191,99,86,191,49,126,60,88,248,239,77,144,125,181,25,196,123,78,114,70,207,103,187,119,127,7,246,196,82,232,95,4,76,188,170,10,185,10,249,57,247,78,93,81,10,14,139,134,25,60,16,165,239,89,189,69,168,133,114,121,247,22,246,54,44,29,67,238,198,37,142,134,173,131,189,224,64,241,59,54,158,124,55,117,104,2,184,210,168,4,164,225,134,108,244,237,154,193,94,149,17,218,230,164,194,234,2,8,25,23,79,140,191,84,149,253,240,181,107,168,88,46,30,184,253,125,115,117,61,185,122,206,1,239,228,185,28,213,30,168,232,76,89,28,251,234,184,71,169,6,29,42,72,117,255,134,209,120,115,227,226,239,161,82,91,235,191,34,134,134,128,55,44,159,6,39,232,181,61,114,188,118,214,2,105,182,62,183,122,84,207,124,222,66,109,158,41,203,126,141,164,176,162,114,111,122,122,239,240,218,44,106,195,187,164,168,72,199,130,119,182,33,216,142,242,97,80,102,100,199,43,201,169,121,99,201,100,81,210,224,27,207,49,116,16,179,11,175,71,70,223,122,187,49,141,117,150,153,46,95,169,161,138,110,119,205,161,203,209,111,125,200,250,223,74,88,243,226,120,97,123,234,127,234,33,153,104,43,92,143,166,76,214,76,11,227,61,155,198,232,172,159,246,164,92,164,249,251,137,72,133,171,239,209,138,55,53,164,85,155,230,66,126,6,154,27,2,171,130,86,65,25,136,103,32,51,8,10,134,47,130,143,235,248,203,68,199,228,167,190,60,19,217,169,120,193,224,98,190,245,188,54,1,32,126,82,5,13,215,78,222,122,156,202,56,3,153,129,240,211,204,32,134,139,190,82,113,225,77,213,52,231,59,120,6,15,118,171,160,150,94,175,95,190,79,244,218,233,196,66,173,125,55,49,9,206,218,114,145,235,122,198,16,58,53,179,179,179,185,74,192,176,203,216,213,224,117,147,51,185,85,216,126,20,84,201,58,227,49,79,94,215,110,222,136,52,79,248,236,212,221,238,113,143,199,147,240,115,70,183,204,232,92,226,227,100,126,1,231,184,167,97,63,24,213,20,200,114,4,175,31,77,200,226,57,155,21,14,128,238,243,203,203,16,157,44,121,146,239,25,8,207,80,194,8,227,145,10,167,144,253,70,183,146,184,107,207,71,234,121,52,30,62,168,21,180,189,234,147,93,129,93,215,154,13,177,37,199,248,18,159,122,203,35,118,189,193,215,73,27,135,211,170,143,169,104,176,9,225,4,63,168,102,89,130,33,46,43,148,248,111,89,223,70,79,241,0,233,191,48,157,174,65,204,223,113,229,221,215,15,22,252,251,128,119,137,29,73,115,7,115,73,250,81,176,233,207,163,184,23,156,34,58,219,111,147,48,204,71,164,126,180,160,39,165,65,91,158,104,245,42,120,69,21,199,26,140,248,115,139,208,80,242,78,126,224,46,176,191,167,136,187,28,197,81,235,50,88,54,54,112,203,117,163,130,115,57,133,72,2,89,26,215,136,10,142,138,201,169,175,74,179,133,250,250,105,39,252,10,147,253,64,198,13,241,51,30,31,250,41,238,209,255,141,242,144,215,161,61,42,183,214,43,61,130,42,154,235,118,28,211,96,249,154,165,192,31,161,160,246,71,40,196,188,212,233,44,82,83,235,222,171,180,91,234,176,207,110,169,61,255,112,64,154,174,183,25,17,252,93,202,55,114,40,77,122,114,238,192,84,122,175,223,194,254,187,195,245,107,240,133,50,47,90,113,87,163,235,170,123,56,18,18,171,206,36,165,109,30,246,176,71,30,235,6,161,214,72,88,35,81,200,93,246,27,15,130,23,5,106,44,141,62,167,93,154,13,93,142,174,49,61,185,248,182,38,102,95,184,75,1,198,243,245,34,124,68,78,161,2,113,95,196,149,212,127,125,228,198,175,121,120,106,129,109,238,61,64,88,107,216,194,209,1,231,165,214,67,197,6,14,186,127,86,177,120,206,122,202,234,146,30,153,152,24,65,42,26,218,83,185,1,235,5,191,116,94,119,190,11,154,2,62,71,154,59,215,28,180,78,168,176,22,189,246,42,144,4,208,207,15,119,120,236,27,231,183,169,31,195,191,243,83,131,171,57,175,144,66,235,246,251,11,18,221,155,73,26,138,107,213,222,249,153,238,189,215,205,195,239,238,8,116,93,111,120,214,100,245,145,47,82,114,223,172,255,185,182,92,164,202,200,197,131,71,12,149,36,37,164,33,67,240,183,116,74,8,198,134,59,242,7,31,148,131,228,121,231,67,117,91,94,217,169,169,229,240,20,201,22,137,40,231,148,217,155,57,89,52,249,149,44,184,57,70,198,93,239,179,240,161,138,145,51,29,62,146,97,124,68,69,40,168,188,212,229,247,142,109,56,220,42,135,43,86,85,122,154,249,51,125,242,196,147,133,235,29,21,245,77,138,74,43,188,101,235,254,114,19,91,23,109,208,47,74,232,2,128,68,142,19,191,38,157,12,25,69,86,64,102,188,235,229,18,240,100,213,119,46,119,51,195,106,184,244,201,133,59,160,132,84,255,34,27,71,82,235,48,133,251,175,88,63,165,216,42,172,229,171,0,105,184,114,209,28,52,114,29,166,40,214,3,146,223,141,214,225,4,29,29,112,229,110,183,225,163,252,185,220,233,222,101,244,99,131,94,16,57,75,200,9,245,205,243,134,252,220,81,1,12,180,52,240,209,122,163,81,251,83,56,180,204,249,121,140,15,125,233,145,15,253,6,173,234,192,13,219,26,223,21,89,151,34,106,78,142,171,242,55,9,120,195,228,111,102,192,231,60,28,48,159,229,208,191,20,255,90,197,251,231,80,87,226,237,171,16,181,76,157,43,75,196,158,68,106,4,11,126,187,222,77,84,121,239,158,29,13,214,25,200,119,237,131,60,249,135,215,109,119,184,61,105,158,186,193,181,173,222,122,60,249,250,21,250,84,189,59,215,140,108,115,141,220,70,233,174,161,113,147,145,173,41,211,139,251,165,187,23,109,208,247,196,182,100,228,234,232,180,75,218,10,5,126,45,252,16,99,196,127,226,166,46,91,4,168,184,101,207,85,139,159,124,154,2,199,99,123,131,98,120,101,92,146,246,11,156,76,175,198,237,79,255,72,150,39,229,157,63,135,255,244,253,31,6,157,174,131,74,139,174,212,220,61,241,161,119,19,215,135,78,70,126,43,9,184,18,205,21,203,207,114,28,107,206,14,254,106,30,222,144,35,147,67,196,109,238,244,229,243,250,66,71,220,121,224,44,162,167,102,244,106,12,150,44,210,184,1,68,137,15,131,237,124,13,3,225,35,210,199,68,55,125,55,78,133,255,38,205,247,176,18,78,39,243,146,173,110,146,221,159,137,66,162,211,190,151,164,89,138,15,123,55,173,229,151,214,186,162,100,249,127,124,161,220,22,104,84,10,27,75,47,174,255,49,242,98,40,180,97,48,94,92,171,121,136,100,119,154,141,224,166,192,152,125,146,220,245,223,89,184,235,205,162,67,251,20,208,183,124,71,187,91,23,33,5,68,42,49,81,150,197,171,74,24,34,6,230,155,255,201,216,186,240,171,207,64,88,40,94,174,52,138,121,126,217,43,199,68,30,19,247,17,195,49,204,250,28,67,49,193,92,192,71,12,143,100,62,70,98,131,11,243,240,107,7,227,29,163,226,191,131,18,196,30,47,26,169,33,250,217,250,143,88,226,5,181,0,99,254,238,237,85,216,99,109,237,233,132,23,183,163,227,57,164,103,15,123,115,203,22,57,47,151,167,201,88,217,172,3,25,152,160,81,247,238,36,204,193,4,130,1,121,247,16,189,96,204,85,63,167,142,128,137,186,154,82,109,110,184,213,78,195,228,111,181,150,60,82,254,162,95,242,87,147,105,138,135,3,228,125,87,99,228,142,90,166,246,22,213,207,102,86,242,66,203,126,21,206,22,254,194,152,24,27,59,202,148,185,212,45,164,211,57,239,118,61,160,229,255,65,181,163,232,46,23,220,120,97,109,237,172,120,243,226,217,85,167,166,68,149,246,158,178,130,234,46,197,3,73,204,19,161,249,223,149,207,110,47,205,77,225,191,5,15,214,208,127,104,126,237,80,190,43,163,77,245,249,168,192,242,26,131,138,50,186,0,80,55,39,240,139,7,114,116,82,128,20,124,52,176,156,154,124,150,228,79,199,90,133,204,225,238,128,242,211,252,193,0,225,107,0,39,64,217,180,253,121,244,251,109,233,40,28,53,214,34,158,16,139,216,35,71,131,156,36,12,196,193,125,96,234,31,218,237,19,97,66,11,251,168,240,50,135,36,154,171,53,175,144,62,58,87,71,27,58,21,190,79,29,203,173,239,25,124,107,71,12,119,215,152,102,6,188,38,59,40,146,35,254,89,95,47,50,183,204,114,155,112,110,188,182,237,161,184,245,19,90,53,166,239,101,111,42,40,239,62,174,125,153,165,198,16,174,178,237,113,155,43,59,76,47,124,97,226,240,80,46,198,135,104,191,90,78,164,249,117,186,252,216,123,36,105,50,57,197,167,98,98,17,221,166,227,84,170,185,239,214,213,3,25,166,204,41,246,170,117,81,87,249,201,77,104,39,44,198,153,156,62,202,200,177,244,159,217,247,191,194,45,75,83,48,55,199,138,212,191,91,11,10,161,206,162,126,36,94,22,114,170,57,184,223,107,189,250,204,28,106,173,172,71,247,66,97,20,53,176,8,63,228,202,198,197,81,63,92,35,153,50,169,143,90,208,23,193,241,194,146,73,250,226,254,86,137,200,9,87,202,151,191,105,108,146,143,161,24,99,87,62,148,46,74,23,11,237,141,203,166,231,4,227,132,56,177,250,227,201,100,172,88,36,85,56,78,183,135,168,137,12,90,229,164,167,82,113,147,162,76,33,56,48,132,26,107,241,7,42,114,2,42,124,180,161,96,9,61,245,132,15,155,109,21,233,33,31,58,108,36,251,52,232,7,173,106,186,63,85,208,156,245,23,85,80,215,155,123,59,28,141,113,108,175,10,175,45,242,74,249,94,106,30,113,103,51,117,78,141,231,253,100,249,235,10,222,247,39,177,92,164,17,125,226,234,10,100,57,228,245,33,144,19,68,237,37,98,58,242,245,10,213,244,136,53,223,194,17,83,205,213,62,135,21,92,131,247,177,241,195,89,115,25,25,51,50,172,241,53,19,77,55,43,254,154,151,98,102,24,126,142,135,203,131,185,217,76,50,124,99,4,126,219,33,175,248,229,106,191,181,217,221,162,21,255,52,53,100,211,75,45,56,152,50,88,178,75,1,139,34,124,83,180,78,173,112,133,228,111,34,98,169,130,175,10,218,171,211,184,144,252,47,200,220,124,95,164,19,90,196,221,129,140,126,247,167,18,44,197,54,96,17,106,241,96,41,70,121,154,164,211,98,217,84,38,238,183,250,115,67,156,38,138,47,170,109,243,3,212,75,76,127,92,38,138,135,86,141,225,148,195,210,211,179,231,34,150,18,27,197,213,199,178,180,155,129,86,17,14,240,11,162,90,23,121,207,117,250,68,78,141,1,197,166,154,49,41,129,109,138,126,248,114,166,170,150,54,58,183,33,124,221,65,149,244,137,244,31,112,24,97,99,233,62,66,108,190,144,183,57,127,41,62,92,253,204,234,199,7,102,159,212,36,242,217,249,198,217,131,249,6,202,222,236,199,15,235,152,148,25,139,62,244,193,51,212,84,114,74,178,63,203,122,12,69,121,38,156,88,182,241,179,14,141,42,98,25,196,16,183,189,88,28,70,197,158,184,111,55,152,142,27,204,185,163,89,90,11,73,41,28,22,3,93,165,51,203,116,205,194,254,25,6,36,125,250,23,117,21,188,0,161,239,12,162,34,217,214,251,126,121,31,208,85,29,177,10,137,39,69,137,108,166,253,11,169,183,217,37,129,188,160,33,80,183,74,13,71,242,3,95,48,115,19,113,80,246,253,246,26,15,115,109,38,78,253,142,115,70,203,139,134,23,218,114,62,206,158,191,214,138,87,90,134,91,214,158,159,237,84,144,9,15,241,24,8,107,51,188,81,202,45,124,99,158,7,253,181,20,203,155,164,250,158,89,64,63,89,108,180,202,253,111,108,113,137,226,85,158,20,221,22,32,71,226,244,242,200,51,71,103,245,245,141,234,206,247,191,231,202,88,235,166,51,235,222,212,125,47,97,113,255,246,214,191,123,98,240,42,67,44,52,92,7,25,18,114,85,254,142,152,88,116,205,99,3,173,172,134,87,114,0,87,16,144,99,113,163,15,222,84,60,205,179,191,113,26,20,7,65,12,14,120,164,102,70,92,254,77,224,135,54,13,198,230,253,111,171,85,16,224,4,140,186,32,150,183,250,163,173,87,211,43,105,64,30,170,255,167,166,217,158,42,162,72,58,45,24,96,74,22,122,184,187,49,132,88,107,226,46,72,19,244,70,197,65,30,95,224,142,20,76,151,86,141,33,104,88,194,198,238,35,63,154,227,238,23,201,238,8,5,180,187,89,218,243,88,116,38,189,166,86,234,175,234,187,119,5,143,156,115,253,155,243,10,123,103,197,240,102,166,30,121,119,77,239,33,30,27,133,253,72,230,200,14,27,54,122,155,41,34,30,128,190,116,153,107,137,59,172,75,163,106,62,188,185,142,59,18,55,82,97,20,87,237,158,124,53,23,228,24,185,95,95,182,80,92,82,162,69,245,221,180,119,250,243,15,255,217,235,176,140,37,185,59,131,95,194,93,15,122,158,93,54,167,21,121,97,126,231,124,150,124,64,52,68,71,240,230,155,127,128,144,125,148,153,249,70,144,189,122,249,3,243,248,205,225,83,10,201,48,104,39,17,29,55,150,155,124,196,231,111,44,223,210,225,197,69,157,43,74,217,184,173,181,66,237,140,239,36,124,207,229,105,198,10,87,244,95,45,29,177,127,125,65,225,29,47,112,23,12,229,145,177,175,197,149,191,156,189,73,141,133,104,138,174,195,174,68,253,42,89,135,245,128,241,32,47,120,188,115,129,104,233,22,205,45,204,48,28,180,124,66,155,159,181,219,117,9,247,191,208,153,109,56,222,52,127,144,208,167,175,202,56,198,211,132,202,229,165,0,35,163,21,186,98,83,45,21,126,68,164,110,104,208,173,80,147,113,181,22,68,113,195,83,133,39,101,224,81,169,125,41,170,127,152,112,212,97,147,122,172,181,248,176,252,37,149,26,81,38,59,187,234,20,245,40,93,218,231,26,181,230,108,167,169,199,115,78,231,131,251,181,185,150,154,21,230,46,6,139,177,165,99,9,154,37,97,8,13,202,181,38,171,104,93,88,253,219,197,47,229,21,92,135,125,177,175,182,155,91,153,62,230,86,237,230,182,28,242,127,127,127,127,235,130,64,203,222,107,69,55,33,1,231,183,148,253,242,75,46,64,114,202,249,47,215,181,103,63,121,189,10,89,195,92,198,154,184,224,26,32,0,16,72,133,176,81,62,215,175,101,0,201,69,31,225,213,113,20,81,81,160,50,199,242,123,223,52,90,240,100,145,19,248,152,18,134,179,240,36,67,185,120,146,162,116,81,67,20,252,201,152,58,204,249,56,6,18,212,173,51,77,219,140,40,100,253,11,251,253,244,170,124,78,235,243,133,134,102,238,210,155,247,227,167,84,14,53,78,94,142,209,33,81,111,191,205,228,134,123,213,54,216,50,38,170,80,78,194,95,111,166,11,89,229,70,25,142,22,145,134,244,135,191,165,83,74,163,232,245,204,170,222,236,218,171,180,163,158,149,139,59,248,78,228,114,154,255,132,202,7,93,68,92,189,83,44,208,84,102,221,178,224,182,235,221,180,50,251,180,245,113,74,64,243,101,192,108,120,227,143,186,250,152,213,98,130,71,92,191,88,52,33,207,227,113,13,85,203,143,102,55,41,149,63,46,119,173,190,228,103,117,105,63,126,105,135,139,147,182,135,100,133,122,120,239,94,180,33,114,215,170,184,176,239,91,219,132,147,200,43,115,18,158,130,90,120,149,191,70,11,151,19,133,177,193,210,81,44,215,165,178,178,224,165,32,160,40,21,37,191,122,77,5,71,113,17,34,208,38,70,11,50,128,17,162,255,14,222,16,176,235,21,230,49,237,85,21,152,231,3,5,221,156,20,114,48,212,29,4,74,180,243,112,65,50,86,102,6,44,196,198,4,13,21,152,3,183,100,130,251,26,19,56,164,99,108,244,169,23,245,199,103,238,71,253,193,121,103,27,113,183,245,229,62,108,210,197,208,84,165,235,107,31,19,187,92,251,172,55,235,252,185,169,183,29,77,12,93,88,165,40,217,18,213,110,57,101,115,93,21,102,36,224,13,19,102,172,212,181,135,29,45,188,224,9,57,155,105,31,186,85,83,109,55,196,61,151,33,45,58,91,125,88,102,111,102,101,209,228,149,177,16,66,171,120,218,207,164,103,219,100,25,183,136,152,205,215,201,18,161,93,185,90,187,86,227,238,187,34,148,186,24,54,25,223,73,189,38,109,124,180,89,244,219,44,206,86,192,41,129,173,92,242,246,103,26,58,10,115,200,13,27,14,186,111,100,15,23,57,113,255,47,0,55,3,153,177,144,72,88,133,40,210,118,32,127,64,58,255,143,39,204,90,203,145,65,196,71,110,121,187,161,24,163,220,97,198,0,11,17,229,120,152,143,97,94,123,212,65,8,243,251,250,109,40,59,53,129,175,19,17,69,120,244,241,46,42,210,26,207,55,166,193,21,203,191,211,205,224,249,217,223,185,71,237,134,161,247,6,109,226,79,93,145,248,143,52,172,123,143,169,77,42,103,218,194,61,222,112,23,100,174,53,69,75,230,242,183,228,217,251,181,208,169,222,148,190,11,253,195,255,33,157,235,185,142,58,89,242,118,113,178,248,198,133,15,35,10,46,16,121,246,198,76,129,207,58,247,164,109,31,191,249,30,71,120,81,57,87,59,247,96,110,50,32,49,77,42,131,63,103,175,232,100,230,171,245,214,242,213,88,45,185,91,19,173,221,115,234,172,18,183,102,8,206,189,139,216,239,154,223,196,68,235,167,149,33,90,105,30,142,125,175,208,154,210,61,162,191,191,202,206,79,1,35,237,90,191,245,79,32,78,102,148,153,127,133,229,136,38,101,230,172,113,93,210,251,246,0,74,76,137,102,195,169,132,212,135,2,201,140,168,184,220,254,171,183,86,45,6,191,115,176,172,34,86,17,33,111,255,27,154,10,85,230,7,56,65,211,127,48,137,197,96,250,43,129,177,44,142,157,85,25,120,60,15,250,156,129,83,223,243,183,144,58,131,173,176,106,93,30,3,44,95,249,183,112,192,12,160,170,193,128,194,171,148,58,90,139,235,207,61,111,45,40,28,249,196,194,100,107,85,188,33,244,71,20,15,185,30,91,248,181,80,28,94,155,117,137,131,158,71,124,136,137,253,170,64,170,19,166,64,90,61,51,80,194,234,36,161,70,180,63,91,185,192,36,82,172,101,252,178,126,157,48,238,198,62,30,198,130,77,98,84,164,42,228,201,101,80,87,109,47,68,31,111,124,147,146,9,76,120,141,214,250,178,102,64,215,83,190,173,190,117,209,6,169,210,135,247,104,0,227,160,153,79,103,15,245,54,132,132,155,79,78,169,82,141,241,212,206,0,209,218,145,127,226,34,251,157,247,82,121,70,195,127,194,86,229,44,45,147,23,26,198,5,40,250,189,212,36,87,57,147,88,214,136,167,97,156,65,104,80,134,69,41,188,144,205,249,116,66,122,228,70,150,136,39,227,136,34,18,11,89,89,49,108,175,130,94,81,62,35,33,36,248,121,36,159,120,241,1,103,17,113,109,198,112,218,92,111,180,113,79,247,71,2,7,167,64,21,180,10,10,72,26,78,66,170,144,226,21,101,247,201,41,19,141,235,85,18,240,165,215,1,183,111,96,178,215,25,154,77,85,217,251,11,107,255,162,34,40,227,113,246,121,23,76,151,142,127,202,17,88,229,68,101,149,33,145,8,242,189,89,193,53,212,230,124,239,157,157,90,101,83,197,172,49,120,190,241,213,29,129,119,117,6,35,79,197,100,254,180,77,174,195,227,31,195,55,3,150,139,166,246,14,186,207,184,148,101,214,213,121,51,183,119,143,29,28,247,242,119,37,166,15,50,217,106,191,6,121,69,127,217,60,230,11,103,105,158,8,224,156,229,217,223,105,97,216,197,134,61,59,149,115,250,61,177,213,106,223,63,40,183,114,25,232,226,249,106,169,75,181,98,104,255,70,156,167,121,22,213,228,41,17,129,82,42,135,165,154,156,232,35,201,174,8,235,173,30,230,244,92,184,171,116,237,127,150,145,149,41,19,78,212,114,116,255,59,69,209,16,212,184,145,77,237,30,255,112,90,157,166,81,201,34,10,22,5,211,87,75,100,163,5,121,110,240,204,86,118,20,115,39,93,188,199,212,225,160,88,36,26,186,1,235,3,147,65,205,185,116,95,229,159,124,150,15,25,65,67,92,18,67,159,95,178,9,72,163,206,64,137,9,128,199,186,170,208,46,26,122,214,248,244,232,100,74,169,91,146,157,95,117,252,89,195,161,113,167,117,111,78,179,89,67,107,115,168,252,116,251,247,108,194,173,213,30,174,219,209,179,98,185,246,27,104,222,224,26,249,87,76,132,143,72,131,250,240,129,43,19,231,40,231,236,150,179,241,247,46,115,87,213,61,115,131,174,143,172,245,221,154,123,219,112,243,176,222,182,105,191,217,237,253,64,134,241,230,229,106,178,222,220,162,162,214,243,140,176,46,25,167,3,87,39,13,213,3,245,149,111,233,85,253,83,45,176,220,187,169,70,243,105,179,151,21,14,80,162,161,208,54,157,152,7,58,83,109,109,210,206,234,127,189,90,66,180,2,118,25,214,11,25,38,21,50,224,211,7,147,128,16,21,61,71,131,161,71,96,31,160,64,149,125,47,40,140,34,181,10,185,199,28,173,255,50,252,140,71,94,159,15,160,125,22,5,107,120,27,239,103,240,48,55,234,63,174,181,50,164,7,204,182,74,6,121,193,177,25,122,219,28,126,52,242,10,137,9,17,176,14,35,102,210,251,136,134,222,152,74,6,189,26,240,67,107,124,131,190,137,81,135,183,209,208,24,129,157,159,133,185,99,118,106,175,179,219,158,26,74,97,165,153,48,221,224,1,125,30,203,221,10,169,215,199,191,39,47,248,185,90,51,10,109,31,183,188,121,22,55,162,186,203,226,100,52,102,192,94,122,239,49,173,158,210,150,181,179,217,18,42,233,44,147,207,162,46,32,129,116,71,38,152,60,2,206,70,76,185,189,98,105,11,224,252,188,231,40,51,156,36,22,41,199,39,155,111,77,108,113,141,24,194,171,253,72,86,221,246,30,191,40,92,222,226,105,63,249,250,3,126,184,86,235,35,246,130,91,26,65,114,32,55,77,151,118,58,180,122,161,191,105,209,59,212,89,254,117,151,2,188,167,223,94,188,30,135,87,250,79,204,36,146,180,231,127,123,112,253,224,75,13,110,55,229,127,211,118,117,152,30,142,51,220,38,155,141,1,166,88,30,245,44,9,38,0,116,188,125,215,100,64,69,44,127,131,217,38,74,17,37,209,9,41,8,192,185,109,173,223,148,25,157,136,219,222,20,253,84,200,218,203,37,212,148,32,46,45,39,123,145,128,145,72,225,217,200,186,37,224,127,21,203,64,254,240,247,80,233,79,153,232,212,140,56,254,182,170,210,6,130,232,220,219,166,45,74,220,112,51,191,39,152,72,58,165,237,107,31,62,232,78,87,139,176,161,71,20,134,144,238,164,199,125,74,141,119,246,133,183,43,27,109,215,30,53,29,79,82,53,109,71,124,120,88,87,91,43,68,182,222,66,244,97,45,253,243,112,180,181,223,187,207,104,77,173,219,174,71,34,172,73,100,226,40,150,68,26,23,246,110,140,241,154,131,112,229,88,29,174,132,113,160,98,117,223,51,8,73,60,60,200,227,217,134,200,165,83,74,228,41,139,191,255,23,72,169,79,132,79,194,254,121,9,211,218,40,234,244,95,247,178,24,111,181,221,153,34,62,93,181,120,201,180,138,120,242,249,103,101,7,114,198,109,21,249,95,4,53,231,235,3,191,24,36,131,251,180,145,63,8,26,255,16,78,8,3,236,237,171,194,35,76,123,175,161,221,190,40,157,170,185,6,149,23,183,166,231,213,222,220,50,121,30,184,206,26,155,106,217,172,121,111,83,105,94,234,26,56,253,179,56,113,49,195,216,152,45,154,75,91,130,121,108,144,243,117,77,235,200,228,183,103,106,132,165,6,156,164,191,46,194,244,54,71,20,155,14,81,248,27,180,39,159,40,175,83,41,103,91,22,167,95,87,90,25,75,126,207,60,80,103,46,83,59,157,233,43,49,60,155,114,170,122,52,188,177,56,192,26,249,64,9,243,158,131,80,154,20,204,203,187,52,73,244,96,232,27,242,169,124,32,76,63,213,211,93,233,209,249,127,22,248,239,80,155,47,233,243,140,183,65,110,216,72,185,91,38,224,254,237,251,140,70,244,0,97,194,111,117,84,210,92,3,126,234,206,88,160,168,15,217,163,235,162,97,182,236,170,153,138,54,122,29,80,34,146,110,101,156,41,160,190,189,66,139,181,112,86,221,128,41,42,247,128,145,66,252,64,194,245,219,153,46,171,57,152,184,49,18,44,4,13,157,102,30,230,91,135,53,56,188,205,74,7,128,205,237,21,218,0,200,216,128,23,151,98,71,130,138,121,186,119,236,161,128,244,135,171,137,99,182,139,78,14,29,85,128,46,236,93,112,234,208,124,210,234,146,151,71,2,127,155,144,105,224,233,35,65,53,122,49,147,142,237,205,201,178,241,113,15,170,101,35,32,61,133,44,103,228,216,186,118,51,188,78,148,197,30,217,130,243,231,11,75,30,100,15,127,16,86,79,254,222,177,182,180,186,201,121,193,217,162,161,108,160,184,164,196,205,148,255,119,37,244,128,54,246,39,84,126,123,249,116,145,194,64,208,165,75,103,232,141,211,151,125,89,91,10,33,149,113,75,152,153,132,57,130,18,239,41,27,47,78,47,114,23,109,141,93,145,89,29,5,254,62,112,134,184,176,24,165,48,203,198,164,238,94,255,195,40,250,136,194,56,123,67,247,168,133,34,40,84,219,174,102,170,158,49,223,75,196,198,97,212,13,178,105,174,163,68,158,209,163,116,81,46,85,228,44,52,118,76,243,26,170,255,166,22,104,104,226,139,101,194,206,58,186,37,6,240,54,123,180,163,213,99,156,41,206,20,32,17,15,91,69,16,127,253,244,26,216,188,19,115,75,218,253,164,222,235,148,195,100,252,254,22,247,123,233,128,107,123,235,219,213,21,84,31,213,221,25,27,57,50,98,247,96,249,24,25,19,85,243,187,249,89,202,239,10,25,185,225,146,27,102,50,5,89,166,200,121,117,6,35,49,133,114,119,85,154,116,35,178,156,58,106,72,245,165,24,203,86,147,46,123,133,97,251,102,162,94,155,30,223,138,83,161,133,125,221,82,77,167,183,245,243,250,252,107,191,252,158,177,203,18,226,178,246,181,175,45,222,207,12,214,226,152,216,155,248,162,84,182,197,191,49,175,173,148,49,20,34,64,222,8,187,40,123,182,233,182,242,28,197,145,170,34,118,220,16,120,51,192,19,255,3,94,167,128,49,76,84,122,193,3,83,249,131,8,36,238,203,66,161,171,52,45,121,195,43,133,137,255,162,9,34,71,101,156,0,45,211,19,156,22,46,41,7,111,214,129,52,191,223,3,146,10,115,130,130,227,60,88,250,207,101,183,150,83,193,20,75,69,151,4,144,122,251,10,149,137,157,94,202,181,222,236,97,134,221,213,165,50,147,78,100,7,52,15,41,185,75,3,50,128,159,177,184,36,110,184,116,220,61,205,176,115,122,75,30,218,36,213,91,38,158,132,135,194,125,168,115,81,200,22,245,48,53,86,46,237,9,227,252,208,91,145,41,71,71,235,157,134,201,239,129,18,180,249,153,202,109,81,187,187,79,37,210,233,84,175,108,121,164,222,68,208,176,200,203,56,196,65,207,83,23,46,167,95,204,129,103,250,164,76,209,159,97,29,254,94,41,11,174,143,75,22,66,70,20,44,118,236,43,139,119,182,62,63,25,179,108,189,19,211,48,21,193,250,223,183,0,126,98,143,154,121,34,34,117,47,46,195,139,21,60,235,151,82,76,196,99,76,87,180,63,230,102,60,156,105,235,165,37,150,179,85,245,227,201,56,146,76,126,246,184,251,37,237,92,99,240,15,114,113,82,102,166,255,116,209,246,243,38,77,176,15,24,150,239,1,110,235,40,142,254,224,2,104,109,56,135,223,6,254,193,206,219,106,119,129,125,212,12,199,248,56,227,136,38,97,230,23,133,10,13,123,172,243,121,68,7,114,3,166,192,255,71,167,254,243,224,210,112,186,216,37,52,82,36,18,12,186,248,101,31,115,219,42,177,144,149,27,238,191,22,164,170,204,23,207,79,40,183,33,222,25,29,149,79,236,170,27,152,188,55,161,110,110,165,107,254,166,180,212,194,240,144,44,183,54,153,223,65,185,202,126,31,254,245,169,97,251,205,214,39,194,215,66,110,102,208,248,83,246,254,221,163,139,147,13,26,30,140,141,33,160,32,165,99,83,130,51,18,194,5,63,165,78,31,100,212,205,237,215,57,127,191,224,165,184,99,18,146,22,160,140,83,64,169,22,159,215,216,22,199,26,190,204,123,166,104,74,46,48,24,231,168,173,163,179,172,87,118,92,195,94,213,198,91,164,240,82,99,84,140,126,186,59,210,110,149,69,214,168,145,170,188,215,177,18,195,53,177,123,65,252,180,227,46,135,192,211,91,218,255,231,181,158,127,91,227,116,127,55,107,21,77,57,64,45,160,0,231,242,7,23,163,211,163,87,117,217,239,9,88,61,130,35,191,74,230,173,198,73,213,167,219,112,175,228,98,28,71,140,203,212,112,167,215,233,84,213,69,115,11,5,63,8,236,172,158,120,4,17,61,20,245,237,106,95,13,54,30,101,70,137,74,77,222,4,63,100,254,244,107,120,17,74,0,185,235,120,228,204,133,240,23,86,99,112,107,241,219,184,199,11,231,234,119,253,185,25,243,136,52,83,242,129,21,53,20,47,173,70,180,127,95,135,186,59,38,134,218,35,174,231,237,196,228,248,180,49,114,252,183,97,155,121,211,247,143,139,238,143,70,147,61,21,212,34,187,197,190,117,109,147,203,25,43,23,245,11,182,234,204,180,163,100,37,146,100,133,132,227,105,212,156,34,126,60,181,12,226,154,173,120,247,184,161,64,219,53,244,139,26,227,249,239,220,127,240,128,56,161,246,180,158,204,244,83,189,152,26,136,250,239,35,7,130,68,116,234,40,93,87,39,148,11,22,82,164,254,43,225,159,191,226,17,246,43,135,17,166,225,157,120,102,128,130,116,34,210,121,40,19,56,194,251,84,81,18,157,75,12,176,146,102,204,156,201,47,204,196,204,251,17,21,115,34,249,79,91,61,250,218,114,145,175,183,46,116,175,203,108,247,175,248,126,106,162,238,6,185,175,64,34,42,242,243,251,10,62,57,154,247,251,48,172,184,4,37,33,171,237,23,118,252,117,185,108,229,68,231,82,135,3,216,109,51,38,145,151,95,137,212,247,90,249,94,84,203,13,181,88,110,14,198,125,189,122,253,177,57,255,133,87,253,182,207,226,188,101,221,66,253,12,147,200,167,205,94,150,165,110,196,224,23,218,185,134,171,43,55,156,116,195,126,249,182,69,42,173,135,212,213,172,87,96,11,201,80,2,153,66,111,238,27,110,171,191,244,149,26,52,244,191,71,105,172,232,30,53,165,85,208,253,160,50,127,151,232,238,138,8,54,148,166,98,179,240,111,163,104,20,235,77,85,58,227,115,18,112,139,199,127,181,183,233,117,77,217,174,82,50,80,148,233,123,91,143,81,95,230,254,187,139,146,25,154,245,95,39,198,124,149,10,14,229,7,114,49,73,171,48,56,242,14,32,185,176,22,151,197,191,163,150,88,88,14,225,126,47,250,137,116,55,80,125,4,149,51,230,9,95,97,74,67,89,124,67,231,220,233,98,181,158,172,24,197,151,171,230,22,250,49,230,103,153,198,141,168,12,220,210,175,185,149,247,158,69,175,238,250,216,232,196,81,246,77,243,252,55,74,246,71,29,38,77,96,52,222,155,90,141,200,235,148,234,103,217,202,111,38,110,151,95,191,7,74,191,103,148,47,189,245,33,242,154,78,61,75,169,143,230,36,22,43,189,241,80,110,107,11,194,73,73,170,18,192,102,122,239,117,82,162,68,131,240,151,183,251,40,217,159,159,73,181,176,4,205,183,201,203,135,26,140,252,62,73,250,60,119,183,43,211,88,170,28,87,155,58,191,76,164,179,190,233,248,183,186,41,54,229,206,201,140,185,91,255,153,16,107,222,161,120,197,179,41,163,208,255,236,15,250,244,214,105,56,71,58,70,174,219,245,128,174,144,202,176,4,156,8,214,226,228,146,147,132,129,28,78,4,199,233,98,255,134,90,82,119,195,134,175,63,161,65,35,55,96,253,96,150,48,112,62,227,177,121,228,204,197,19,121,113,173,180,186,0,2,83,78,143,136,53,28,202,236,106,255,186,53,52,243,59,128,68,151,90,203,247,58,52,81,213,15,90,144,101,90,231,127,147,78,229,150,102,71,24,109,218,7,96,49,119,246,230,73,108,238,235,52,26,255,131,141,115,81,222,249,23,151,139,212,212,51,29,29,190,92,152,132,235,92,5,107,20,95,15,154,75,219,189,23,43,122,127,15,148,115,183,28,103,188,88,135,115,92,113,34,89,226,183,210,124,157,225,30,82,221,97,88,43,124,235,91,118,104,239,243,165,109,18,255,12,207,42,30,137,175,73,27,112,244,241,238,69,27,180,247,57,39,251,6,154,19,43,232,155,246,167,228,47,53,244,255,43,19,10,105,52,218,20,230,59,144,47,185,59,160,156,20,192,146,117,3,241,71,17,210,167,209,137,1,130,40,145,115,47,114,223,40,243,182,48,188,64,119,91,39,178,3,201,207,173,74,11,210,253,253,114,149,104,64,119,229,59,192,159,239,49,225,54,88,112,23,148,151,104,243,97,176,228,161,93,212,31,255,176,65,171,45,211,93,180,117,65,162,179,17,178,158,96,74,186,143,24,135,64,146,57,212,59,70,97,208,73,177,187,168,70,35,173,55,202,253,228,136,119,177,99,67,98,36,63,207,153,38,38,158,50,63,113,104,252,166,253,62,76,111,9,149,228,189,180,70,18,168,162,103,1,117,78,151,17,91,25,113,125,20,165,122,188,57,83,106,177,16,230,67,244,166,238,169,205,17,188,45,2,160,139,125,178,214,29,254,230,189,204,173,205,35,22,95,85,207,68,247,94,169,229,230,114,251,161,172,31,222,189,121,171,167,37,71,67,8,254,222,22,30,132,202,20,51,144,136,28,95,25,190,51,14,194,151,181,26,168,122,127,104,128,54,157,175,95,59,136,58,167,145,125,32,226,193,155,10,203,252,123,212,101,213,98,21,17,93,217,46,203,160,250,167,207,227,76,113,50,151,167,182,79,170,62,43,219,198,222,1,204,237,117,80,46,10,180,249,95,180,237,215,97,87,5,246,116,59,8,245,245,255,112,132,117,88,15,152,126,7,232,238,217,226,79,84,81,22,251,68,202,29,221,24,47,180,179,62,238,209,35,243,165,163,93,29,77,173,77,83,57,10,225,123,244,48,151,165,185,218,111,227,158,163,105,220,57,253,131,2,125,85,109,134,82,219,220,66,247,130,172,146,233,176,225,105,76,88,208,33,201,225,172,8,216,133,172,35,62,45,205,138,206,99,227,242,59,230,155,197,156,36,186,52,153,163,89,233,230,122,99,172,105,175,138,176,121,41,182,145,72,196,13,84,188,223,36,119,239,217,131,76,6,53,37,19,159,4,53,223,6,182,47,174,154,97,180,128,233,133,113,176,80,224,153,82,154,158,122,69,7,223,238,23,88,84,228,73,121,30,199,101,210,133,114,79,216,158,139,39,37,42,238,11,215,149,48,12,115,69,54,246,10,205,160,68,16,219,220,42,34,132,36,135,6,76,6,67,131,57,255,28,234,105,15,23,240,152,102,29,22,38,219,81,240,47,165,102,46,131,38,146,166,59,227,50,115,115,190,3,104,62,32,144,93,135,17,83,93,85,2,152,43,92,27,234,221,129,169,232,86,137,189,88,145,241,25,8,136,130,172,89,165,24,11,8,27,117,230,152,158,203,215,46,181,94,142,59,62,148,244,236,98,122,88,19,137,182,58,252,106,170,161,117,88,146,144,160,172,214,207,200,198,248,130,84,220,187,42,79,134,251,135,67,133,106,249,218,216,245,3,251,99,121,237,101,217,237,39,110,74,206,171,159,237,135,164,194,76,170,8,55,26,242,62,148,137,224,146,134,21,36,205,62,241,192,118,96,79,164,254,38,82,132,123,255,62,207,244,67,103,244,9,28,70,236,227,201,250,247,111,23,33,82,5,212,183,72,172,104,163,122,64,66,170,127,249,179,31,190,239,87,69,224,208,134,27,245,46,165,152,12,153,52,218,41,237,224,252,85,221,152,110,66,226,205,73,56,40,0,100,198,92,91,207,49,192,31,86,142,88,178,42,189,200,51,208,82,229,9,83,27,138,155,201,98,94,172,108,130,4,117,190,8,46,149,145,35,72,99,224,200,36,6,117,19,105,188,112,54,169,61,142,52,81,95,149,72,191,46,203,71,212,161,111,63,97,186,62,126,161,22,253,242,72,163,235,78,250,230,202,231,183,66,206,129,199,188,21,108,167,139,163,34,90,27,187,130,7,181,174,70,83,62,42,255,117,247,239,45,75,63,120,173,41,100,246,159,55,166,212,10,92,99,67,140,254,179,154,239,130,133,252,164,237,97,92,135,53,88,94,225,80,225,94,227,250,163,73,27,190,226,92,30,17,3,247,16,79,112,138,40,18,141,176,85,17,56,82,225,46,63,208,219,170,176,127,227,57,29,69,39,132,1,44,171,199,128,91,51,134,181,129,126,50,157,213,92,127,254,5,201,130,197,184,195,249,29,24,68,109,155,194,2,243,142,109,26,246,163,181,106,237,246,229,238,37,164,253,64,133,242,99,188,226,225,80,52,235,100,146,176,81,78,162,20,187,68,242,139,164,207,148,123,199,38,93,57,82,161,79,177,63,139,216,134,66,189,199,111,207,239,126,226,125,238,70,98,113,107,195,131,199,159,200,124,41,165,236,168,252,6,86,230,190,172,211,220,220,83,61,223,125,4,128,46,159,46,199,79,30,62,2,70,140,147,118,25,126,94,123,153,7,232,178,249,156,158,46,77,193,176,144,185,58,0,9,173,107,244,59,222,27,24,92,27,69,198,171,250,108,90,154,182,233,244,2,102,100,151,151,11,1,64,87,240,54,236,226,242,128,7,119,26,20,55,67,41,227,156,69,135,61,127,89,112,18,119,34,114,137,103,216,178,232,133,188,85,255,248,230,12,9,62,67,44,84,180,76,156,46,33,49,75,64,10,126,180,28,215,184,174,139,119,233,195,78,65,240,25,75,223,193,221,56,224,195,121,175,241,226,78,237,197,133,63,118,9,14,85,144,208,231,97,128,233,227,200,222,45,127,33,238,135,208,194,154,14,231,96,182,72,92,28,108,228,180,103,41,248,220,237,18,109,236,205,15,68,234,168,88,60,66,13,21,189,7,101,79,22,46,247,33,248,213,161,250,61,0,187,52,239,82,183,63,187,127,79,122,14,83,176,234,242,139,51,76,32,224,120,121,247,204,186,169,117,149,117,14,76,3,183,78,83,48,250,180,100,57,16,226,235,244,242,159,119,40,53,212,238,243,112,213,111,60,136,149,168,67,89,73,80,95,169,150,159,117,231,183,172,105,179,147,78,166,128,60,250,109,103,101,197,151,172,118,139,214,56,234,142,206,116,54,57,108,171,77,146,31,113,159,106,236,244,126,21,173,61,13,144,194,1,211,201,119,179,86,122,122,103,19,43,172,9,76,128,230,30,13,215,50,89,240,36,69,97,85,47,69,61,29,202,160,19,72,139,41,62,66,195,215,48,190,77,109,13,192,151,186,234,94,216,87,26,144,22,164,56,75,189,184,189,174,140,147,144,162,184,31,2,202,144,92,7,248,46,101,190,159,217,21,239,91,240,154,67,231,56,54,137,14,202,199,152,58,241,9,192,71,197,139,238,195,82,220,144,118,131,89,215,113,4,102,106,243,55,98,252,117,195,175,162,98,184,77,124,255,45,223,204,85,200,219,8,49,142,83,228,252,70,217,11,144,123,43,36,104,25,178,107,124,120,145,8,62,218,5,99,160,10,119,80,48,85,230,87,114,2,141,152,192,70,42,43,114,175,128,114,194,218,103,17,73,237,94,245,223,237,13,119,188,43,161,249,130,232,8,77,65,244,203,107,124,149,203,98,24,9,49,50,210,103,33,32,253,179,123,246,55,137,37,68,89,208,52,12,230,75,150,174,123,132,22,43,113,84,58,35,69,164,216,60,217,234,163,107,157,248,4,28,61,253,242,207,224,207,151,247,46,197,56,13,64,159,15,222,15,78,16,36,87,248,63,83,53,31,165,225,204,51,1,102,106,47,189,131,170,189,202,53,45,128,7,102,172,14,216,192,108,97,5,137,48,73,169,240,66,45,48,26,52,98,7,31,91,105,90,119,64,113,105,255,98,151,43,157,151,237,61,138,227,185,121,245,117,106,139,116,176,24,25,126,96,117,50,133,105,240,246,205,178,227,7,132,95,48,234,180,105,6,184,80,54,94,160,249,216,140,23,140,187,183,53,109,109,43,80,22,135,16,2,243,218,112,113,223,102,139,178,5,106,158,4,42,241,11,113,140,28,31,108,220,172,237,1,114,250,40,111,159,19,188,158,37,176,9,199,148,111,69,62,211,229,210,247,102,201,34,121,147,174,232,94,218,203,23,217,32,179,163,117,251,246,32,43,54,199,190,95,203,213,116,138,132,148,138,154,22,197,72,200,143,43,48,0,248,199,154,137,59,11,31,150,105,1,19,96,146,90,191,57,99,159,206,5,117,144,234,5,68,154,85,105,133,219,174,176,213,46,11,191,230,98,157,179,149,116,43,32,1,87,2,142,61,45,6,171,13,151,117,113,83,150,233,9,23,34,146,57,187,200,189,109,77,80,19,52,10,3,40,60,180,35,253,243,207,160,255,236,155,23,138,160,7,97,185,123,143,67,88,72,67,81,12,114,184,103,231,162,30,82,79,253,227,221,185,237,228,46,148,154,221,66,17,107,140,147,57,5,226,27,30,29,192,214,37,133,246,152,83,204,170,50,244,126,46,137,145,230,17,69,199,145,21,127,188,42,220,203,179,219,210,239,70,92,104,236,247,48,53,101,186,219,107,220,143,177,118,225,21,70,120,114,13,26,107,121,35,134,184,73,95,246,201,206,213,9,234,213,202,111,119,155,50,26,91,143,202,53,176,121,152,220,151,203,158,246,108,189,200,11,88,231,22,212,94,127,234,187,137,248,87,152,45,172,236,29,62,83,163,150,141,162,149,72,239,204,2,31,23,40,236,187,98,20,143,132,143,32,113,3,171,200,234,50,48,109,27,25,77,182,0,154,248,128,130,38,160,2,117,164,151,206,195,79,112,19,192,7,46,49,172,65,192,252,71,86,88,150,235,225,162,251,126,246,238,70,174,185,84,114,159,85,34,249,1,117,187,72,95,126,64,202,8,101,129,190,46,98,102,16,121,156,26,5,235,7,243,245,174,46,184,161,10,59,226,94,199,211,184,47,252,134,0,84,228,18,177,70,52,194,39,181,227,168,40,55,118,135,95,131,155,137,36,235,35,2,223,67,238,39,75,223,102,252,138,224,91,186,105,252,121,123,50,187,193,231,21,212,229,243,103,68,150,119,27,188,12,34,121,111,159,3,199,73,195,201,37,172,105,120,23,166,249,110,77,176,129,230,207,65,9,42,131,250,70,213,245,206,169,64,10,62,36,184,143,218,42,108,141,14,173,168,234,47,181,239,210,192,77,57,204,11,251,97,140,83,199,233,226,206,119,182,16,69,191,33,188,108,90,75,170,23,186,184,60,244,9,20,210,240,11,119,228,62,7,22,29,192,26,131,109,49,16,207,241,175,224,171,66,128,175,192,86,83,171,19,140,34,102,115,238,132,229,63,2,221,5,212,83,223,193,52,193,95,254,120,83,56,180,222,254,201,158,250,227,206,224,234,42,145,223,141,89,84,143,69,253,247,86,248,25,61,37,78,100,14,253,181,119,226,3,94,106,242,42,248,196,201,96,69,200,29,90,40,235,50,223,73,147,125,224,144,175,251,184,170,81,234,246,130,143,166,136,45,250,234,82,200,207,135,141,193,47,149,3,195,96,182,189,16,213,44,165,157,196,190,65,14,236,144,220,108,64,221,5,244,114,111,124,11,74,199,13,47,160,40,212,226,111,165,176,253,142,145,31,69,86,65,141,219,0,180,106,44,67,211,240,68,34,178,104,27,196,18,36,22,141,66,27,91,49,135,78,53,160,188,109,254,9,228,250,219,117,100,213,58,34,117,58,147,113,158,213,87,40,94,31,133,16,252,9,179,63,52,225,1,83,120,65,52,76,248,61,152,230,100,122,228,31,40,0,116,103,81,13,144,191,100,0,63,86,97,226,88,197,237,205,207,125,248,243,70,145,112,164,157,225,30,1,89,159,138,109,42,28,194,249,68,118,70,17,55,221,144,94,129,250,66,153,31,215,94,76,221,121,252,166,88,41,177,95,33,171,136,243,48,221,38,227,9,165,89,5,113,106,17,175,215,109,31,20,191,238,153,104,193,160,128,182,112,59,203,222,154,148,175,144,163,190,47,149,57,84,244,10,67,27,98,149,86,23,194,104,240,128,24,189,121,239,38,225,1,90,75,63,5,87,2,26,199,2,121,178,85,26,96,31,192,240,9,45,48,99,209,151,185,135,196,196,157,196,157,28,58,213,64,77,192,17,194,161,174,37,17,176,124,116,15,209,180,154,172,6,231,1,214,255,208,130,200,55,140,48,125,92,180,192,138,213,154,139,147,22,49,221,69,24,58,15,99,17,107,36,0,220,255,142,130,60,127,64,237,143,113,116,218,128,245,129,158,182,27,141,112,169,15,143,238,50,66,149,162,8,124,152,148,52,8,165,66,168,135,222,89,47,32,68,203,219,216,127,197,13,60,37,184,207,16,194,74,118,166,50,249,146,218,39,63,113,64,157,125,101,117,34,254,41,84,153,234,96,51,105,229,185,159,39,205,156,81,223,105,220,233,217,172,53,53,212,254,16,121,30,203,38,143,203,122,28,243,193,68,107,87,109,110,182,114,33,24,125,136,139,153,152,152,92,77,179,152,63,132,109,147,136,76,183,26,91,88,45,10,30,241,188,218,62,55,54,50,158,67,119,109,212,190,54,141,124,51,93,49,227,80,113,23,39,168,11,96,78,12,57,215,53,103,204,246,240,229,158,88,232,228,148,93,121,43,90,121,238,18,77,253,166,2,246,35,248,48,174,213,77,19,15,11,12,252,5,224,64,252,80,86,189,150,137,165,49,197,30,56,129,113,180,127,230,92,242,180,188,146,50,163,238,101,11,109,80,54,15,184,119,148,50,13,22,100,0,20,251,183,184,62,141,75,57,19,111,201,116,166,218,126,218,178,216,89,48,182,192,19,216,160,108,89,111,109,213,45,129,237,46,28,77,4,126,13,26,151,247,197,228,157,97,103,22,64,199,27,74,24,140,241,71,15,205,244,103,1,211,214,230,145,167,101,47,28,51,30,190,249,126,209,117,77,66,50,17,58,251,155,63,205,1,54,147,226,129,170,150,92,212,151,98,219,56,52,128,33,5,165,115,211,8,174,222,184,31,2,6,62,197,251,160,59,226,241,251,22,120,85,77,144,40,14,1,118,194,108,38,150,31,32,186,192,174,17,31,16,135,196,217,85,20,71,183,1,245,132,214,208,46,139,32,229,164,210,23,213,93,15,157,103,94,157,246,179,8,127,130,53,4,234,208,227,249,176,25,175,0,245,143,0,133,84,94,178,174,46,94,29,122,244,81,46,110,174,21,47,50,151,112,190,88,189,152,197,110,90,233,240,245,123,141,75,77,211,193,5,217,92,51,126,246,164,95,126,1,180,182,0,170,193,11,190,27,10,157,18,6,42,156,34,168,34,134,146,229,227,183,244,101,54,22,139,205,19,44,59,172,239,31,38,130,253,124,224,21,214,46,254,28,17,252,121,209,89,164,129,116,10,90,125,14,187,143,188,120,181,2,142,69,1,109,224,17,212,212,139,82,73,3,209,6,235,238,126,41,179,29,234,231,154,12,13,75,134,98,68,252,92,184,173,174,11,174,132,190,153,173,34,246,246,244,59,98,44,190,131,123,137,90,26,26,132,177,217,59,148,127,91,191,178,237,57,1,98,118,32,9,48,208,50,153,30,232,248,166,245,99,112,213,248,133,25,238,253,102,169,56,152,20,252,123,209,24,102,95,222,138,51,64,223,7,117,193,79,204,115,32,247,111,20,130,252,116,231,202,215,37,169,2,114,252,27,169,203,185,231,115,49,233,221,247,166,235,30,93,226,133,203,199,234,193,227,146,166,138,170,37,84,62,99,85,175,204,74,128,57,232,150,150,86,242,18,28,68,64,93,92,154,131,175,220,11,127,198,178,250,26,118,110,23,252,211,185,213,111,147,215,28,220,96,182,80,192,173,69,66,80,48,89,224,153,145,245,227,248,146,129,185,178,202,51,202,140,151,204,211,212,30,155,49,253,71,30,197,193,48,224,154,161,23,62,10,122,116,190,102,241,81,118,253,208,232,78,63,92,151,84,74,175,104,205,85,5,14,37,126,251,136,249,129,39,79,228,141,117,174,95,183,229,177,104,123,48,82,110,126,192,235,76,179,102,101,32,202,78,180,162,125,215,215,151,142,150,238,201,147,46,190,56,229,222,55,21,125,23,69,173,193,186,46,117,65,107,75,120,249,168,25,139,105,236,200,8,53,204,52,216,250,178,11,2,132,224,127,66,128,165,218,227,179,114,243,241,67,24,38,228,114,79,23,104,7,19,174,220,101,10,46,67,199,125,119,156,154,129,98,45,144,206,80,144,26,80,111,163,147,52,191,141,139,140,184,214,38,26,132,97,54,186,1,24,6,129,176,241,211,227,150,190,190,174,141,116,200,152,6,160,105,243,34,16,48,209,5,134,237,19,104,216,246,183,209,136,46,196,232,252,104,159,133,135,38,90,2,30,140,150,65,98,189,14,193,175,173,7,11,139,67,25,80,135,4,21,188,11,108,167,96,31,1,195,91,204,94,164,214,22,182,106,163,37,8,34,183,78,102,44,77,155,125,123,107,38,161,208,71,0,218,28,251,12,175,245,102,229,34,237,253,23,185,123,181,140,197,176,155,226,254,40,169,30,46,82,154,164,132,0,206,247,114,154,76,119,110,237,78,213,41,69,241,167,84,8,48,191,134,169,169,13,205,30,226,250,45,108,211,190,240,191,120,182,250,100,222,246,193,131,248,78,36,145,9,206,168,199,202,52,163,206,26,111,215,181,84,73,117,41,17,45,255,80,86,219,196,236,83,43,112,82,9,75,195,93,210,187,3,253,180,190,71,28,42,147,236,140,194,48,96,226,216,167,163,107,163,17,28,251,8,154,161,241,124,246,10,194,199,200,165,203,253,165,26,36,246,55,226,197,48,24,124,97,7,182,222,53,171,167,241,114,194,245,226,14,113,13,30,103,115,123,77,69,129,218,142,75,134,68,50,232,36,112,97,169,26,6,56,34,95,239,154,206,233,25,55,2,155,27,8,107,250,181,173,166,130,55,189,137,95,133,169,253,200,215,222,79,64,17,231,23,8,102,152,57,184,115,1,225,44,142,22,27,1,86,93,164,207,192,0,240,76,100,31,138,187,132,217,185,180,248,137,158,202,31,182,169,186,224,243,96,120,153,179,49,232,57,197,89,19,120,198,250,212,216,184,155,157,25,31,154,153,188,107,123,22,135,4,113,91,82,151,153,75,152,148,85,179,86,58,54,233,88,173,0,135,5,170,60,17,24,94,162,244,235,215,253,170,233,165,24,104,232,122,193,96,182,72,40,125,215,84,140,72,124,171,90,96,232,205,98,16,127,254,238,202,202,230,202,153,222,166,213,190,225,137,72,92,2,224,246,218,123,222,76,71,56,1,22,204,142,191,44,135,93,74,236,137,32,177,5,156,105,205,111,48,151,219,136,75,146,90,87,90,246,252,31,45,199,1,61,67,113,209,200,152,44,214,240,125,220,3,190,22,217,88,18,216,45,208,22,118,217,139,184,8,56,27,10,102,172,173,46,77,249,45,41,233,112,11,221,112,0,222,72,68,22,68,234,206,84,241,106,141,50,107,108,118,49,71,31,118,12,233,214,130,243,130,216,12,105,236,165,36,206,250,26,132,153,62,80,108,135,230,27,44,6,23,244,12,84,111,239,171,7,215,124,211,231,172,217,17,235,118,92,191,127,162,221,144,96,18,102,137,191,190,184,91,118,52,97,47,99,47,111,207,83,86,119,217,230,41,220,47,190,164,214,186,123,35,9,38,143,243,101,9,206,247,48,58,236,6,238,230,243,130,26,241,230,158,224,249,25,110,192,140,96,186,140,45,4,220,28,65,166,185,131,126,45,89,7,194,151,192,241,144,239,252,59,212,251,169,23,115,118,121,220,220,205,167,193,160,203,98,131,160,167,35,39,253,252,113,222,33,24,26,197,8,66,99,24,187,239,200,207,207,238,98,43,95,13,72,95,126,133,161,188,46,165,58,224,248,115,139,174,75,152,149,43,77,165,149,188,171,186,91,236,33,238,245,89,193,189,11,40,189,13,85,139,136,224,169,181,63,79,216,91,118,25,122,151,111,229,250,84,159,21,220,147,88,133,182,174,125,157,160,73,173,25,176,76,110,37,95,209,117,124,134,142,58,233,205,108,133,179,88,168,5,221,234,240,208,141,184,199,127,53,158,132,153,207,142,40,89,16,134,47,96,15,248,5,160,135,64,65,145,20,114,164,93,81,69,227,241,209,229,153,46,176,50,52,67,20,208,234,178,251,252,121,224,102,1,30,176,103,216,108,80,224,181,49,171,40,105,106,26,11,222,53,6,63,102,222,184,81,1,131,119,12,111,226,241,80,12,224,113,54,78,31,55,157,20,7,181,34,57,107,113,112,185,117,80,231,71,241,219,88,28,8,124,94,196,181,33,18,77,128,204,60,167,253,86,95,101,67,220,87,176,0,158,84,227,178,116,190,226,168,21,106,131,207,10,0,214,96,107,112,145,87,106,232,1,208,158,219,111,225,9,90,35,248,132,43,79,238,23,140,165,9,191,227,32,200,202,198,156,89,128,225,45,71,243,247,189,135,66,117,151,183,199,30,72,242,63,63,218,57,184,110,214,134,135,6,55,47,157,201,158,197,131,114,248,117,250,51,15,228,17,245,254,20,56,113,184,170,237,102,0,234,160,6,18,45,127,167,125,115,194,31,127,220,64,32,89,48,151,114,174,215,215,130,159,86,1,108,95,132,128,5,68,207,187,180,171,33,231,84,62,177,86,61,70,75,235,36,253,5,187,160,80,104,240,220,26,7,116,112,232,163,77,34,218,45,88,168,151,139,116,97,129,122,175,50,165,228,169,121,21,46,229,28,92,35,234,222,239,85,135,84,117,163,206,127,25,234,78,15,1,56,145,217,114,240,16,25,39,200,123,231,100,233,103,249,189,246,245,33,49,225,83,240,7,244,96,234,219,14,236,126,24,24,248,10,31,186,164,219,0,238,186,0,175,79,26,199,167,172,136,238,233,154,174,18,162,242,214,161,60,249,91,96,112,44,133,78,24,96,243,80,77,6,45,177,20,198,230,55,123,16,28,21,228,243,96,16,81,211,58,151,173,149,132,12,1,214,206,58,242,168,103,233,227,228,156,134,100,27,72,130,206,145,117,22,224,254,210,113,43,203,42,219,102,211,13,188,178,123,74,171,230,1,86,146,24,6,101,2,142,131,199,15,213,251,199,69,61,45,26,203,92,142,50,2,27,129,177,211,114,97,128,51,211,4,68,1,230,11,187,1,145,217,246,65,84,216,2,27,252,207,67,92,234,41,251,190,219,205,203,122,160,59,50,27,184,200,128,189,162,96,22,170,1,17,45,187,87,42,138,235,103,171,79,114,79,172,190,10,22,210,50,236,153,91,199,169,233,235,223,97,26,158,238,124,97,133,157,152,206,83,179,62,140,254,100,47,94,169,69,162,79,163,74,203,24,144,67,30,245,172,98,244,203,30,24,180,244,177,225,240,160,138,162,137,162,233,80,206,251,213,249,130,244,254,103,172,206,199,134,243,65,51,183,253,129,176,213,71,120,11,21,93,98,234,96,216,192,122,187,78,170,80,30,91,190,80,156,219,16,85,136,80,93,132,46,169,98,17,63,128,4,15,76,49,161,237,243,91,180,237,243,211,198,234,13,139,221,39,62,48,0,233,88,146,137,99,92,129,166,155,60,196,179,158,234,214,158,28,62,155,214,9,184,177,110,171,138,14,63,27,190,35,113,189,100,24,28,149,75,124,129,172,124,66,247,148,5,130,171,166,62,19,191,120,233,162,177,248,34,97,191,230,217,198,33,108,4,196,179,7,31,218,187,200,116,231,80,123,123,34,215,22,16,229,245,58,38,6,109,33,178,115,254,85,147,210,224,148,196,192,206,142,197,67,29,191,75,228,54,160,254,53,133,186,137,142,112,88,253,187,11,1,137,145,129,188,150,233,99,80,29,255,171,125,120,72,91,73,41,92,165,157,255,219,21,48,9,247,14,95,215,130,62,118,170,22,139,227,115,250,69,132,255,245,116,183,221,120,67,14,197,120,170,81,108,80,139,134,189,109,254,192,34,223,241,161,43,125,113,122,36,111,126,164,155,202,53,205,204,141,242,217,19,55,112,170,135,223,20,59,170,174,29,191,113,198,199,35,251,190,179,205,105,24,54,85,42,209,4,131,162,223,86,14,61,203,93,243,188,52,189,219,191,2,146,40,68,33,127,9,235,21,125,251,240,244,86,240,233,132,182,79,47,150,104,129,218,215,215,227,98,38,240,102,192,233,44,194,186,243,22,223,239,67,238,24,70,24,122,195,167,44,24,127,237,233,150,67,31,228,103,174,80,88,192,45,199,242,199,13,40,164,1,206,175,160,128,191,59,38,204,108,118,214,186,196,172,88,63,218,11,213,199,174,176,158,172,227,25,227,26,117,229,108,135,227,235,222,222,181,140,153,19,22,214,119,160,19,89,254,70,16,181,222,111,165,138,123,207,172,209,233,9,180,189,16,247,33,116,7,191,217,160,63,246,155,208,206,120,182,34,81,221,254,153,76,163,92,48,50,174,196,180,78,184,124,181,138,22,236,47,135,54,153,150,33,171,156,78,222,235,241,78,229,171,150,164,58,167,153,159,187,238,207,250,136,179,111,21,111,244,183,103,148,55,141,226,113,107,113,173,60,247,34,141,251,135,192,23,36,135,31,234,0,160,56,82,241,23,231,122,158,146,199,71,80,10,14,173,210,219,63,204,16,128,160,134,164,11,20,210,164,175,99,136,194,55,126,67,165,146,122,225,82,167,211,206,36,117,3,103,50,51,25,43,157,71,224,196,55,145,133,22,159,121,7,178,64,47,1,46,48,78,46,176,188,105,249,87,210,124,246,38,194,237,179,179,101,233,8,116,227,55,114,219,178,42,241,17,19,56,157,145,223,71,129,239,247,15,120,147,118,139,248,187,250,30,233,167,141,97,88,223,208,195,136,206,253,156,110,34,38,63,243,207,6,97,229,175,130,183,15,136,152,4,223,33,107,112,208,139,229,150,3,217,151,110,71,20,67,245,22,111,85,39,77,6,222,190,89,156,65,162,151,135,166,191,189,241,74,133,42,21,75,143,33,151,167,176,7,171,30,186,204,84,60,101,236,204,178,194,130,128,178,244,126,75,212,53,25,37,139,152,159,53,44,84,52,219,37,51,241,11,50,175,213,123,2,231,140,84,64,57,244,114,208,1,238,190,174,91,104,11,219,29,36,222,180,5,109,114,62,49,1,45,81,134,9,193,30,96,68,158,204,222,94,218,128,198,143,94,115,209,62,108,2,21,211,83,191,36,221,172,116,37,186,132,201,186,150,103,60,244,130,151,125,217,183,208,196,88,243,36,189,190,114,203,50,99,223,59,76,183,62,207,113,184,162,117,240,123,165,233,65,137,73,181,118,106,194,75,175,245,67,125,109,169,59,136,163,240,130,13,250,223,225,160,225,29,180,139,208,109,176,191,24,230,145,15,154,179,131,161,24,147,199,120,196,27,188,250,156,95,175,212,43,153,25,135,196,155,34,204,247,156,128,119,26,143,185,68,179,176,248,47,8,101,33,206,232,92,238,23,212,61,172,248,197,139,215,126,214,254,29,56,135,73,109,76,11,172,90,69,227,153,254,229,241,180,114,77,38,95,191,55,192,131,148,160,190,252,255,104,184,239,71,40,28,5,0,224,69,82,217,148,189,74,178,247,158,23,18,178,66,66,198,25,33,95,123,111,151,189,87,100,198,133,144,61,179,57,123,75,101,207,195,217,227,112,198,237,187,247,211,251,71,62,92,53,106,144,184,54,4,59,72,104,12,114,199,225,231,67,230,171,59,186,176,244,224,221,46,188,174,145,241,110,134,187,121,4,142,135,78,61,67,134,51,16,137,168,104,216,14,190,59,0,55,217,20,223,247,102,10,51,213,17,200,143,85,154,30,36,78,126,32,0,4,60,73,13,3,162,63,65,35,110,29,98,92,101,8,253,220,18,222,35,4,208,86,131,211,233,83,221,137,169,106,118,226,133,131,112,45,57,105,178,243,184,109,212,166,150,2,150,248,180,119,182,86,179,230,189,199,193,198,237,176,185,55,249,94,17,156,120,49,56,179,100,179,29,129,177,43,126,4,228,192,132,114,180,166,143,38,1,66,64,95,142,13,149,239,159,174,14,36,225,102,117,208,72,28,69,139,124,162,139,66,91,38,248,171,131,191,96,137,226,151,23,15,158,176,22,143,35,48,111,146,146,249,232,165,173,152,222,158,189,128,42,150,218,180,132,178,108,81,228,5,88,168,11,126,18,0,50,186,6,63,252,168,216,218,236,86,225,178,155,121,134,80,179,197,199,81,93,51,174,147,155,28,116,17,251,228,39,241,87,0,177,14,164,42,184,78,96,135,190,73,235,23,95,47,210,32,255,144,105,230,249,70,124,47,18,27,141,93,146,138,222,16,242,12,223,218,68,127,236,82,218,218,42,238,96,120,181,113,239,124,35,209,147,173,38,117,224,9,12,144,87,187,255,136,44,190,77,163,123,79,152,216,178,65,16,18,0,42,51,104,13,0,46,36,61,47,105,148,165,221,58,210,214,200,226,246,51,134,210,175,15,31,160,72,173,183,238,186,60,177,154,252,12,64,68,102,60,138,60,130,135,28,74,32,175,117,121,54,176,89,144,0,67,101,185,119,174,47,99,176,235,134,97,88,145,175,37,71,51,25,109,234,136,244,176,119,90,239,114,246,226,211,196,106,102,191,187,202,255,22,194,183,208,227,18,205,74,103,88,249,82,1,117,45,14,31,117,15,246,105,240,113,35,69,129,107,27,28,62,203,70,63,219,142,0,109,5,218,34,164,132,127,183,241,46,217,212,161,109,74,233,231,33,135,192,63,48,30,73,243,97,246,217,167,180,60,12,208,136,22,123,148,198,206,48,193,177,249,93,254,143,210,15,91,134,41,215,8,26,27,201,119,90,104,24,183,147,255,34,64,14,234,245,181,240,102,143,210,21,228,46,133,24,227,137,26,244,138,116,120,116,159,128,214,61,1,29,185,140,167,78,136,241,200,7,34,163,137,62,196,80,151,236,50,177,91,240,65,92,7,171,149,97,202,0,5,122,248,161,167,32,100,1,6,144,162,184,77,223,131,177,143,252,76,240,57,230,50,157,89,170,251,48,14,40,36,141,169,231,36,10,125,34,242,250,90,136,130,169,168,27,27,235,100,4,147,173,85,143,1,199,245,28,129,155,51,169,33,120,21,57,167,65,45,56,65,11,236,35,150,14,130,226,79,170,212,254,3,26,11,228,199,190,11,147,63,226,120,168,181,74,228,223,36,60,190,59,217,194,68,198,11,57,25,24,123,62,197,101,144,239,170,250,244,180,17,85,209,29,11,47,122,232,25,25,56,207,160,253,75,17,81,137,11,67,143,235,134,104,162,17,247,37,157,74,254,19,227,252,96,241,4,1,240,189,11,42,117,208,68,11,77,130,94,85,59,93,215,148,167,158,126,243,36,22,94,216,31,77,231,75,221,211,121,148,51,65,201,198,88,194,126,59,70,175,45,237,31,148,142,219,204,52,64,220,10,99,108,5,32,185,116,155,106,92,110,191,46,27,86,233,65,37,126,106,250,124,61,78,165,110,228,202,245,162,8,190,55,75,140,152,112,88,125,45,209,194,138,120,64,143,175,56,213,0,48,56,112,30,59,55,199,205,19,95,216,239,45,17,181,19,104,63,126,69,123,77,195,32,19,121,99,180,102,12,174,123,43,225,154,254,8,83,179,37,66,12,123,86,138,247,231,65,223,124,226,207,162,199,3,5,217,160,2,247,251,103,226,166,193,239,15,145,123,237,99,33,170,223,12,2,203,100,221,165,252,7,233,232,140,61,240,228,73,41,210,67,75,155,88,194,0,30,235,146,246,4,116,248,194,190,22,213,31,77,99,196,226,194,220,147,92,117,107,150,27,225,243,239,205,245,94,203,132,185,177,194,169,97,27,22,82,124,103,161,187,163,78,170,98,111,84,22,89,153,194,67,175,124,231,222,35,150,59,253,145,182,15,190,144,203,94,49,24,109,48,77,154,60,76,96,31,134,89,191,102,138,243,210,251,228,210,152,167,255,170,60,150,13,37,254,247,32,89,186,163,118,33,193,92,79,80,169,232,194,137,113,18,202,233,217,152,202,142,172,95,179,29,74,77,202,6,114,153,212,221,28,111,64,83,71,178,159,61,250,121,78,73,172,96,175,233,250,15,195,50,18,100,207,98,155,236,167,95,216,254,143,15,164,97,19,242,126,146,103,93,232,142,179,147,94,209,241,254,239,162,212,79,163,200,174,27,214,14,15,75,127,45,197,231,122,18,110,171,217,2,240,53,207,125,254,205,102,94,221,141,6,8,97,151,213,129,90,91,108,53,135,247,88,105,123,70,206,170,40,196,191,181,95,10,186,232,128,142,36,66,68,108,118,85,49,182,244,125,47,10,98,100,28,157,186,219,130,158,109,148,79,237,215,187,34,57,153,93,235,171,38,223,199,223,146,23,166,180,127,52,144,192,177,52,6,23,225,152,116,141,177,184,126,208,156,211,204,250,69,147,167,171,4,148,85,252,7,151,94,200,146,10,113,218,228,199,42,44,189,53,120,39,233,47,240,3,86,87,147,155,37,63,83,173,131,99,225,167,41,3,41,85,119,87,239,237,6,52,149,85,86,122,224,185,174,57,98,141,222,255,205,15,233,60,246,18,147,74,125,235,171,156,58,175,87,170,60,140,146,7,206,75,231,246,127,108,246,96,184,110,79,136,183,8,173,243,254,53,203,27,7,111,137,189,103,155,33,176,2,105,189,22,239,238,91,143,112,225,210,130,69,0,68,196,106,87,21,117,161,178,29,70,189,15,114,95,171,47,59,233,89,217,175,183,68,186,75,255,209,166,55,111,64,252,155,173,110,214,51,78,47,26,24,246,125,102,29,81,126,12,176,55,150,249,99,80,104,181,4,209,111,90,222,255,99,6,29,85,111,183,30,38,210,240,245,146,11,171,38,118,73,125,6,23,55,108,247,72,227,202,209,192,104,151,176,7,152,116,237,143,133,139,213,22,186,230,235,190,158,182,222,40,219,17,132,155,175,84,133,161,175,47,100,52,91,193,166,125,177,1,56,235,127,214,150,186,186,208,172,225,209,207,227,79,88,239,244,165,79,152,175,182,166,64,89,29,247,125,83,229,248,43,137,2,167,202,21,143,57,40,42,198,181,157,173,118,222,44,66,31,92,55,190,112,34,58,205,22,220,93,33,101,4,96,250,23,162,13,54,91,167,24,61,106,234,66,58,114,234,62,212,212,199,185,12,65,36,213,38,155,255,0,23,80,89,61,25,144,157,80,198,75,154,193,22,65,208,66,7,46,209,252,193,13,24,9,165,202,219,17,242,188,19,213,71,10,121,198,47,10,114,193,241,84,139,51,224,210,183,126,51,47,118,222,68,233,189,132,117,56,205,176,122,96,139,2,2,19,79,49,215,235,127,211,122,148,232,110,35,31,216,250,185,41,186,253,91,249,213,79,82,235,130,239,190,110,47,247,216,25,190,76,232,47,80,92,206,244,108,66,137,157,142,231,206,249,171,117,221,89,114,212,226,239,30,175,209,15,205,178,46,190,135,182,236,241,42,193,30,14,109,9,229,115,28,53,43,132,149,215,217,105,189,124,48,195,40,245,28,127,132,152,82,135,240,238,49,198,134,98,199,214,255,237,145,115,140,240,71,166,255,80,216,129,28,223,164,175,234,186,143,200,86,99,16,75,239,176,208,176,3,210,16,53,254,129,156,49,168,104,232,105,9,89,74,165,1,97,253,34,225,100,110,229,252,146,118,230,84,119,148,171,179,244,51,106,152,207,219,138,148,212,49,12,245,238,85,142,255,88,69,116,152,243,179,251,213,249,218,40,81,63,14,185,163,82,205,174,104,92,83,154,110,163,232,112,119,8,115,202,167,4,185,115,172,167,85,11,99,221,70,45,139,84,158,113,36,66,142,2,72,215,119,51,106,254,141,201,54,181,148,186,254,230,254,9,27,199,251,39,237,94,127,237,199,125,46,30,254,61,143,132,46,59,94,137,112,79,245,65,121,98,7,79,37,17,224,11,126,154,221,116,25,26,130,225,60,128,133,56,165,33,113,68,188,143,229,89,191,140,217,170,33,193,99,101,57,163,8,87,106,203,6,66,203,191,92,161,156,8,153,133,73,51,24,221,199,91,93,24,144,250,19,43,40,73,227,33,207,177,136,48,185,255,243,200,54,223,49,235,0,223,80,60,225,142,156,207,61,206,11,76,127,80,178,29,131,139,82,214,29,187,227,214,170,9,203,2,2,175,110,196,16,233,218,67,254,28,31,91,196,34,187,3,147,20,175,103,199,119,245,166,250,251,88,91,24,112,206,133,109,252,95,200,137,231,79,197,166,190,97,232,116,254,156,140,195,196,24,87,95,186,133,217,241,196,249,217,98,111,183,43,25,36,215,226,157,12,49,25,203,213,20,38,75,210,217,47,59,210,247,25,255,68,70,52,128,80,39,87,44,101,240,73,252,76,119,145,216,185,69,148,190,114,224,44,116,107,206,135,189,101,196,90,151,128,5,254,105,59,37,125,43,189,102,59,123,222,246,19,199,75,15,11,118,60,144,102,146,145,217,111,234,94,115,56,15,151,233,45,132,55,82,94,152,248,12,147,55,233,149,215,82,88,85,254,102,190,250,68,13,124,178,20,84,180,39,246,181,231,178,220,98,210,55,178,16,201,113,106,121,181,104,179,25,246,234,249,247,6,204,139,138,45,103,188,220,40,171,38,155,45,107,132,44,155,175,253,164,38,243,18,22,21,141,92,143,231,234,57,239,43,150,89,251,117,244,103,96,84,121,183,102,113,188,139,80,211,129,203,124,205,53,60,94,61,6,117,33,157,13,60,32,162,31,141,121,83,30,143,220,13,15,237,92,9,18,48,152,73,170,206,36,210,63,181,81,35,253,186,66,72,18,6,83,220,45,103,167,248,75,96,23,234,251,67,21,113,169,32,219,96,237,100,245,7,16,190,250,24,121,179,4,100,16,29,212,219,192,220,200,188,183,178,34,84,24,224,7,195,165,152,46,105,83,97,140,16,66,148,12,180,64,198,52,34,78,203,105,188,105,199,187,222,163,40,164,223,135,42,204,165,139,161,254,51,35,45,207,167,167,59,110,97,151,163,151,172,105,192,249,145,130,47,69,71,82,118,184,82,255,154,155,164,173,134,32,180,29,142,103,30,178,115,150,94,144,240,222,84,95,186,101,51,82,36,164,42,129,201,71,124,151,64,250,52,93,65,166,77,70,97,249,211,35,178,89,27,125,239,237,10,56,31,251,88,167,217,251,138,214,148,171,144,55,159,88,117,130,223,26,209,189,158,98,104,141,165,116,155,13,189,39,49,146,79,140,40,83,33,171,174,158,58,255,83,229,107,28,187,179,215,176,246,201,186,251,0,253,139,83,137,137,114,39,154,35,231,53,96,96,234,99,169,196,118,172,64,19,205,69,121,230,70,171,242,241,98,205,65,91,140,151,10,97,121,8,158,115,82,127,29,23,77,81,178,228,115,30,134,41,103,204,116,192,245,19,125,13,78,206,55,135,74,157,120,239,55,127,117,132,5,78,103,146,159,196,184,21,223,206,144,184,213,225,30,194,128,129,206,96,197,151,234,54,202,52,6,151,94,115,208,243,192,51,165,128,113,105,154,135,58,95,129,140,152,171,114,124,93,228,120,172,61,138,201,65,187,213,99,79,4,47,35,193,223,231,114,48,243,146,252,193,93,126,109,3,214,208,242,127,233,9,73,83,250,85,103,134,137,77,182,104,245,54,239,254,145,112,0,110,139,180,251,96,206,179,101,232,119,71,223,48,254,40,143,231,226,232,202,80,245,171,47,95,81,68,90,247,238,164,171,119,241,54,177,195,76,171,27,22,202,85,240,113,189,195,219,4,57,151,14,48,15,15,123,147,163,116,216,73,60,26,211,61,176,241,203,103,11,218,228,21,4,43,238,207,92,194,214,21,42,139,63,251,119,245,9,191,110,208,119,244,185,58,67,118,7,112,40,61,43,255,175,62,220,27,189,196,1,4,209,51,236,138,49,93,24,22,232,228,125,224,150,38,249,52,225,136,159,74,251,207,89,217,143,81,55,75,145,141,119,93,52,126,199,126,77,199,250,153,113,62,26,60,241,76,231,49,123,76,121,255,206,24,243,180,126,252,89,27,212,162,163,243,97,151,236,189,227,213,68,240,180,151,126,129,180,136,49,97,165,146,198,235,92,255,219,247,79,181,179,183,204,203,172,0,15,61,109,39,230,49,139,40,205,87,138,200,193,169,141,252,3,235,90,249,228,139,183,8,140,144,152,119,186,237,127,133,59,145,33,196,65,221,122,31,82,3,5,210,179,156,1,80,231,81,131,49,214,245,157,249,213,221,112,73,217,255,4,214,199,221,113,70,54,9,98,166,249,135,198,191,164,252,103,249,208,52,59,38,11,56,96,204,72,173,152,50,54,123,24,2,123,86,233,123,48,173,83,241,85,178,205,56,78,131,106,2,200,185,214,247,128,72,245,70,179,173,135,171,212,215,123,43,189,201,171,134,164,217,150,122,237,95,154,45,199,23,6,12,199,118,4,26,125,240,252,76,167,18,156,218,185,208,32,84,74,180,97,187,106,86,234,163,57,77,104,120,3,123,161,111,171,21,161,247,47,38,58,215,86,11,229,32,127,254,108,18,14,54,101,158,114,208,58,58,157,179,213,18,95,248,97,244,253,211,170,87,82,177,37,188,131,38,58,164,8,167,57,207,153,169,173,177,137,5,148,146,126,36,43,157,0,61,72,83,126,112,150,186,91,61,10,188,157,66,250,185,230,66,48,158,185,214,72,105,245,249,126,229,233,101,176,255,146,203,238,121,254,159,95,195,5,214,217,37,95,127,1,150,140,141,185,61,188,198,77,74,99,209,136,159,9,28,183,70,237,89,134,29,211,69,203,13,76,31,87,194,212,39,103,193,6,177,194,192,145,27,212,151,221,52,85,59,16,42,70,181,74,72,63,135,92,133,216,202,134,91,159,75,210,82,82,190,32,25,111,110,32,39,175,159,85,193,191,146,163,104,182,82,190,136,237,44,244,128,24,206,237,239,181,225,101,238,147,171,222,67,59,156,8,4,85,124,213,33,190,160,116,154,212,195,30,240,224,35,81,86,139,144,100,9,243,80,58,55,231,109,31,215,154,190,49,112,130,90,175,2,33,242,173,186,218,103,87,58,92,75,176,89,54,32,75,92,87,167,51,235,230,85,23,9,146,205,166,26,123,200,131,234,117,115,160,73,61,11,88,158,16,137,215,199,51,236,214,253,80,101,246,165,128,137,53,164,179,156,165,41,117,57,127,41,14,111,4,131,48,79,63,238,33,99,225,154,203,250,4,230,168,158,38,28,25,5,99,7,91,163,193,10,15,177,67,78,0,152,217,88,69,14,65,70,109,33,171,163,122,24,46,115,247,1,43,95,18,248,214,26,134,111,199,28,5,44,71,30,211,152,49,17,227,184,219,200,39,157,55,239,2,76,223,69,244,67,143,255,204,50,221,149,27,200,211,250,206,219,164,255,58,231,52,139,171,147,239,235,182,160,249,183,1,80,226,30,207,139,194,168,167,43,161,4,177,242,134,36,9,154,242,33,253,227,63,238,79,61,217,41,20,188,201,128,79,28,56,205,61,23,147,218,16,64,182,171,36,37,194,161,198,128,175,110,225,114,251,91,149,221,177,161,214,134,16,234,81,229,223,138,92,183,51,72,226,139,20,208,80,81,52,65,48,220,180,134,203,248,103,132,108,209,238,76,163,231,153,146,31,34,55,40,61,251,83,25,94,240,72,203,102,5,1,25,55,92,124,231,87,197,89,171,164,51,246,85,240,152,232,209,122,57,250,26,208,54,10,4,114,213,36,29,15,40,210,7,238,33,137,34,12,118,57,249,60,60,251,50,71,189,137,1,164,75,65,54,228,93,45,39,139,150,221,124,156,216,248,238,163,85,161,51,206,54,86,33,194,61,135,145,67,216,143,41,103,168,227,23,46,136,246,179,92,47,47,189,6,192,177,32,208,171,80,49,48,194,152,80,170,73,177,225,111,102,189,195,57,50,31,43,12,248,51,51,206,10,233,184,126,35,183,245,67,42,210,114,83,115,98,185,124,170,253,67,104,84,70,1,146,242,75,210,79,233,233,228,75,193,24,128,238,183,185,53,86,5,107,165,247,105,238,7,209,50,209,50,45,247,203,189,62,33,70,180,221,94,90,189,117,8,21,23,23,228,185,247,116,216,38,222,205,113,244,198,50,157,198,106,71,70,40,3,45,100,246,2,233,237,219,25,38,202,10,119,21,237,10,225,92,24,211,22,38,197,191,121,201,122,9,9,250,235,233,211,255,2,68,16,216,159,33,20,118,159,57,89,198,100,122,231,17,59,153,128,105,149,3,34,235,70,225,105,67,206,149,97,197,9,53,91,79,82,167,15,51,53,252,167,59,118,119,217,133,239,185,210,68,215,58,233,23,202,28,212,233,189,205,12,48,20,200,227,127,27,169,220,249,246,212,40,30,94,168,76,105,60,77,203,113,185,57,106,166,73,126,222,66,81,44,56,171,217,117,188,65,16,248,125,249,22,183,84,65,121,6,174,65,49,61,254,114,251,66,146,63,145,36,49,91,113,196,20,81,155,32,228,2,218,96,178,108,181,35,143,166,224,166,102,195,69,177,5,189,1,33,111,204,90,82,28,198,27,56,54,63,178,4,193,99,235,35,162,239,195,27,121,158,106,84,33,180,40,131,35,98,17,241,148,17,170,3,202,101,109,154,33,113,122,189,65,57,147,49,200,160,9,79,34,105,10,87,120,194,88,199,198,219,8,189,1,232,26,195,166,23,249,89,111,22,246,189,167,193,187,140,136,154,20,193,242,161,234,69,208,67,60,186,30,20,94,246,137,252,195,100,18,228,49,49,83,154,33,131,144,11,6,121,3,8,23,189,108,178,187,100,129,139,19,99,39,20,218,199,38,109,42,7,251,42,12,230,167,11,7,230,10,70,234,116,178,255,126,153,219,74,88,19,150,124,157,186,117,206,47,236,50,236,59,247,243,160,237,50,125,234,45,182,75,56,29,167,131,203,215,104,48,128,104,22,56,222,215,189,60,196,13,236,51,70,255,72,102,18,241,89,194,65,53,225,152,26,49,19,76,79,35,68,96,189,234,223,167,248,218,45,192,2,161,41,172,245,213,147,35,240,154,103,231,128,62,122,199,151,241,112,17,106,203,19,40,161,216,22,38,36,252,48,27,184,185,199,75,224,127,203,41,197,139,5,77,184,115,224,174,231,102,61,56,29,3,47,116,225,181,38,105,200,128,97,196,193,90,154,243,203,128,147,237,169,163,161,180,211,100,84,190,56,123,51,231,53,136,31,196,127,246,192,144,249,109,73,0,74,253,157,130,69,64,128,5,210,111,92,251,120,156,165,245,209,122,22,49,98,152,67,31,232,178,175,167,249,96,73,36,32,178,16,197,24,86,222,187,45,20,126,37,243,165,153,91,72,56,187,97,240,189,14,168,120,21,124,44,8,90,68,45,211,191,66,69,210,216,143,124,248,71,128,134,93,165,22,14,11,236,60,239,127,237,136,116,111,99,90,80,111,183,245,240,91,27,121,9,249,253,156,228,154,149,37,2,189,231,140,28,66,66,59,183,163,129,49,194,115,124,223,220,3,189,10,129,251,127,168,175,166,214,139,181,110,110,19,103,8,52,92,152,103,191,243,181,70,137,236,138,40,5,88,203,108,33,48,52,151,249,45,228,109,159,227,83,151,119,144,74,100,9,214,181,113,218,185,100,183,90,64,214,83,35,135,152,16,49,107,213,227,95,152,121,165,135,78,233,241,193,140,48,239,85,209,231,55,105,55,34,130,203,62,226,219,227,118,129,188,14,101,111,154,133,25,199,175,4,5,65,34,3,160,85,162,212,243,72,144,13,227,240,7,143,7,180,164,137,183,142,95,137,74,196,215,107,232,252,213,88,224,63,171,148,145,237,200,32,87,190,143,83,164,170,66,130,76,132,236,223,178,97,63,49,67,61,231,27,111,199,215,86,42,111,227,161,201,170,121,130,103,187,72,106,101,228,179,113,75,124,118,143,197,223,161,248,65,131,103,63,240,179,79,15,199,142,10,160,8,161,45,189,94,201,64,63,165,21,115,59,8,225,17,36,16,98,189,141,172,224,188,31,25,127,247,11,46,105,251,63,84,175,28,110,79,242,47,176,132,224,76,134,2,86,33,218,25,183,129,63,185,247,201,244,61,150,125,56,223,184,217,35,84,161,40,240,32,184,250,156,44,26,97,230,132,75,164,26,165,64,28,154,245,100,92,15,245,4,31,59,83,43,63,193,79,43,188,240,108,101,117,95,27,234,43,210,2,254,42,86,170,101,10,91,120,135,30,138,239,203,16,152,203,5,248,209,246,145,148,72,107,199,228,109,158,22,126,117,178,116,8,174,8,211,121,44,138,192,100,165,3,162,188,123,195,175,155,53,236,137,25,114,68,150,23,6,204,231,212,145,225,88,198,190,255,98,143,156,95,175,184,129,50,211,82,31,92,132,93,92,59,207,16,95,24,134,101,136,142,73,88,60,207,180,123,50,101,11,250,123,170,250,184,35,150,130,169,27,28,129,158,8,191,92,169,52,15,196,50,6,118,143,38,137,144,76,168,158,239,16,125,103,10,126,249,105,221,42,24,192,152,158,58,74,190,159,126,118,233,128,6,130,82,47,147,47,196,31,48,21,216,213,154,43,88,4,188,249,112,189,126,49,230,147,48,130,134,16,72,84,250,40,56,239,111,52,116,108,119,25,120,129,97,76,102,192,8,137,81,49,81,45,191,187,67,59,18,50,87,91,13,148,215,185,22,132,188,80,111,220,229,135,180,248,117,16,247,171,138,103,203,212,179,187,127,255,133,36,253,30,213,224,89,220,226,216,248,17,29,69,241,223,59,27,13,101,153,86,15,65,154,71,145,141,253,49,93,19,41,193,169,71,122,22,151,140,45,182,67,190,112,131,209,74,239,182,140,194,61,223,8,156,51,1,201,197,195,225,239,36,191,51,238,48,249,10,0,253,45,121,220,56,66,108,33,134,174,251,159,117,68,174,133,230,114,194,67,228,213,124,47,223,198,151,168,48,122,247,30,108,243,173,79,84,22,241,16,218,135,91,205,177,248,237,116,109,117,39,139,252,161,173,245,21,137,134,39,29,116,155,70,60,114,44,212,184,161,167,245,250,221,183,168,176,214,162,223,238,14,123,158,29,222,150,235,174,7,171,219,117,119,156,228,200,31,237,84,79,253,14,156,202,221,110,177,229,10,113,235,46,83,194,246,232,90,107,77,39,179,32,190,209,196,250,13,1,185,119,127,234,248,187,131,102,55,223,97,217,136,87,28,196,16,223,63,223,29,30,244,59,111,63,201,2,77,221,187,120,191,76,190,188,217,165,203,22,136,240,214,82,234,43,159,56,249,229,186,224,93,89,198,32,233,55,125,175,221,163,236,133,173,75,201,73,248,233,231,59,82,229,133,170,254,5,133,184,163,202,65,64,126,111,143,87,39,155,204,115,219,226,57,174,249,128,141,246,149,197,95,46,107,155,117,115,182,214,89,84,229,194,243,93,218,223,138,147,81,158,171,181,177,215,52,149,119,177,83,142,76,168,246,139,183,20,184,43,125,120,203,197,205,91,172,65,161,121,75,233,49,100,112,217,90,44,197,44,59,194,84,253,102,34,141,64,129,147,11,23,84,143,54,32,227,186,82,35,222,127,180,204,63,156,252,57,50,26,177,202,197,251,139,210,175,3,249,219,178,27,94,148,56,178,233,241,39,121,246,240,131,200,86,130,57,59,98,210,178,94,162,113,185,250,38,196,3,74,138,126,79,73,143,65,148,91,154,236,153,32,141,61,239,247,223,42,159,126,106,87,221,204,169,48,176,118,46,242,207,246,228,111,123,250,59,81,131,80,96,139,49,64,16,219,32,54,39,170,216,83,134,17,7,22,42,218,74,226,132,179,252,190,9,57,216,218,146,223,139,6,26,30,95,56,169,22,192,152,35,8,230,83,168,4,233,71,189,245,111,145,112,173,193,203,73,250,102,16,239,125,19,96,31,168,20,68,19,31,110,126,238,57,191,45,164,106,179,253,227,223,190,190,189,56,178,234,215,247,140,160,104,103,197,137,39,141,234,193,93,218,130,173,187,186,57,139,228,226,78,57,99,99,253,192,153,218,243,163,210,169,206,223,124,51,217,100,67,162,92,255,117,36,30,158,135,158,62,212,76,42,82,117,175,198,146,136,173,243,127,199,13,58,198,122,12,211,214,199,219,231,242,19,45,7,210,220,230,25,155,215,104,129,17,124,37,253,50,110,141,212,21,185,165,167,109,35,217,125,51,229,160,195,50,235,112,116,44,138,53,241,209,103,64,152,69,215,76,26,156,61,204,251,207,221,128,231,86,216,39,209,155,3,102,31,10,113,64,30,133,29,72,7,97,198,15,78,201,100,42,0,50,253,75,236,34,71,88,223,225,154,102,83,109,31,250,221,13,163,184,18,141,11,92,150,238,100,46,63,226,122,148,24,181,18,215,27,24,103,216,97,193,22,248,239,242,250,225,211,169,14,51,6,224,78,113,176,236,199,224,233,181,122,58,71,150,127,139,231,121,12,189,121,5,223,188,11,22,197,84,203,55,164,113,34,192,62,74,60,231,184,164,71,22,116,158,28,241,208,206,117,233,38,64,126,92,97,105,210,141,148,229,128,180,242,69,222,42,153,233,104,118,3,176,179,70,52,86,88,172,253,43,79,30,13,228,129,34,54,74,247,66,147,214,41,225,109,223,237,157,147,251,148,30,217,75,196,241,52,34,223,235,100,46,29,116,64,213,55,140,28,16,15,165,63,100,146,247,238,181,186,173,252,239,144,200,108,34,191,65,182,66,63,216,212,73,240,12,28,136,143,225,120,246,82,133,16,244,146,126,50,14,176,247,216,86,76,105,236,50,182,174,247,140,157,50,24,54,242,225,151,43,140,55,41,121,27,89,74,179,216,209,52,10,196,168,111,74,150,244,235,131,73,214,208,71,99,59,133,146,217,61,189,63,248,253,116,120,61,85,218,252,221,215,126,236,206,240,71,138,184,231,93,134,218,41,177,120,244,94,22,188,138,200,231,58,98,247,250,199,2,207,224,73,123,31,30,102,140,252,211,27,216,33,144,197,55,101,150,6,51,180,149,206,183,222,191,101,170,161,43,234,99,76,207,244,162,218,6,7,223,199,3,215,9,85,9,255,174,137,172,130,16,55,148,152,18,254,177,68,230,71,165,203,26,123,88,250,110,115,94,221,183,219,205,78,37,76,254,181,105,122,64,244,118,141,228,124,69,79,145,111,9,27,225,209,169,37,207,180,108,100,51,150,147,6,248,85,216,84,144,60,184,112,7,229,211,65,246,150,130,203,247,249,89,225,108,183,193,89,65,125,104,250,217,115,51,170,221,26,140,100,147,84,112,89,184,107,124,21,228,207,236,171,2,79,241,125,53,160,127,39,17,145,129,30,239,43,2,9,84,24,87,52,252,103,65,164,4,222,40,134,253,26,219,175,97,198,215,52,18,191,174,18,94,71,163,192,60,40,158,90,148,73,127,164,215,104,150,207,50,151,193,212,168,83,123,216,163,13,95,102,161,205,106,24,230,144,252,198,235,90,179,111,244,148,34,165,95,172,27,30,126,232,29,40,233,164,110,75,218,230,182,178,122,22,127,153,236,135,30,138,207,251,77,189,71,195,22,115,69,123,215,241,52,190,201,254,22,180,218,234,50,246,1,99,187,231,217,106,196,118,3,90,181,211,83,28,135,186,203,89,31,168,98,99,34,152,233,121,188,112,103,195,38,6,129,241,234,233,75,85,38,150,75,121,248,33,228,38,188,194,128,64,226,136,30,156,84,3,212,89,143,140,114,165,182,190,44,22,204,42,43,212,3,63,213,18,250,249,95,98,214,161,188,174,146,87,23,167,205,247,142,237,244,59,55,223,218,166,228,7,238,218,13,96,255,123,4,46,246,37,161,255,254,197,232,197,117,59,217,171,105,173,234,72,157,31,180,227,94,18,82,7,138,176,125,39,52,0,127,157,165,196,82,148,39,158,122,183,250,156,90,169,90,172,34,111,48,250,235,203,45,193,67,185,189,140,237,120,111,195,111,14,1,138,182,90,241,224,123,162,230,226,128,109,16,24,102,72,201,203,191,90,83,246,218,118,19,10,165,133,250,48,35,190,244,234,124,167,124,27,239,96,168,72,149,60,24,113,104,19,74,65,93,68,178,70,90,59,226,57,223,145,232,65,89,159,206,9,208,193,17,79,22,204,58,200,130,92,85,94,157,132,187,129,144,144,129,178,245,21,38,235,227,215,61,151,156,251,209,86,192,246,229,152,89,213,27,207,158,109,85,168,215,75,218,119,101,183,134,48,128,221,226,7,117,208,206,131,239,58,44,130,194,196,47,161,73,221,142,207,209,102,105,195,73,219,158,2,21,183,232,221,104,157,188,22,76,221,43,66,183,91,91,44,236,221,83,213,252,221,68,160,207,61,188,212,246,204,210,70,32,52,156,201,163,59,156,90,126,220,58,24,15,93,207,107,7,248,144,26,112,240,175,52,14,147,213,67,63,3,236,46,123,211,99,137,48,12,56,70,157,98,35,181,31,133,67,67,130,96,41,228,111,199,174,3,13,105,88,99,143,40,69,255,146,76,214,89,178,141,90,244,75,13,163,72,198,73,211,52,208,217,231,126,88,6,12,125,20,187,43,232,178,232,198,105,239,202,148,88,125,83,229,158,192,243,197,72,13,91,214,58,29,27,137,19,199,9,152,57,82,170,138,96,245,93,117,122,227,197,34,162,60,224,161,235,15,171,239,154,72,172,10,241,104,125,162,222,255,67,208,0,54,203,241,5,131,153,229,73,128,79,46,235,126,75,48,168,6,240,221,73,22,140,103,139,113,72,3,60,236,186,213,192,169,250,140,21,123,125,41,84,244,111,14,69,17,148,84,236,80,63,186,157,34,23,17,93,59,5,144,46,203,243,240,101,235,224,33,145,55,90,61,34,214,109,243,42,151,231,90,94,54,106,152,150,191,132,98,120,207,40,23,107,215,32,198,112,230,55,147,149,87,6,21,193,204,27,173,155,43,226,123,224,208,197,6,79,156,211,72,63,76,149,81,187,149,193,68,110,239,96,128,23,252,201,68,190,9,41,137,204,151,182,48,77,217,111,199,39,42,6,160,161,95,175,249,197,132,65,38,181,100,237,27,105,74,219,122,41,111,209,67,247,183,235,156,192,65,131,150,13,221,231,18,52,161,242,80,228,103,210,13,211,70,158,134,94,124,147,210,229,188,84,126,44,201,213,201,18,87,192,189,219,216,190,127,18,164,6,95,8,196,19,25,179,195,242,200,183,137,155,99,84,94,196,88,14,133,147,65,93,71,173,15,127,211,184,105,114,12,149,154,47,204,244,90,94,142,208,9,206,226,166,212,1,44,241,29,104,39,80,10,104,129,156,40,132,130,124,188,179,166,31,154,78,84,246,36,58,23,227,218,67,81,125,74,12,15,150,170,172,199,240,92,167,166,249,120,174,135,201,151,188,203,203,25,22,135,68,225,120,194,86,136,85,182,227,36,197,141,152,99,190,201,163,248,151,116,205,98,132,218,79,191,63,92,168,244,169,58,111,245,134,223,2,150,195,212,175,67,49,224,144,156,122,114,252,28,77,196,86,94,187,93,60,223,31,106,162,142,234,72,234,82,35,212,97,78,183,52,32,72,224,33,190,88,141,231,242,229,161,177,28,34,53,240,194,103,28,51,153,203,50,193,23,35,60,117,62,20,92,143,1,141,236,137,61,237,135,25,35,203,8,70,216,22,235,22,5,66,127,123,187,152,50,246,99,111,130,14,238,102,248,243,106,113,232,57,236,114,118,149,165,222,157,38,255,187,142,237,171,152,127,23,102,227,108,40,195,53,0,120,176,94,40,252,105,69,237,224,187,247,230,82,39,42,147,108,244,94,184,88,68,155,136,27,95,244,138,201,65,220,127,226,127,113,134,6,42,50,231,221,158,254,224,194,240,91,45,174,211,56,72,167,25,183,9,233,39,37,42,171,213,155,35,80,51,6,232,112,132,84,191,173,216,190,59,11,224,236,16,186,108,114,181,199,55,218,57,240,117,8,213,247,13,108,4,204,14,193,197,228,214,255,67,151,70,236,78,129,8,120,195,61,134,51,46,54,97,38,28,104,232,153,171,134,181,37,43,225,222,221,225,113,114,44,147,60,133,79,237,170,50,183,255,38,225,194,222,226,226,192,196,206,89,193,199,204,138,144,224,82,111,132,252,173,148,33,215,0,146,27,145,62,90,59,107,228,201,226,219,243,157,230,201,54,4,222,116,159,75,33,218,228,118,207,170,79,60,141,128,198,125,213,244,205,122,202,86,81,13,147,132,131,154,86,207,11,211,9,34,91,61,1,32,199,229,58,100,206,159,17,14,203,27,91,97,178,155,134,253,66,90,9,245,12,51,159,158,251,18,195,217,29,56,47,76,133,94,2,46,109,49,36,254,70,254,213,205,248,84,197,69,181,88,179,96,244,232,192,179,235,161,35,254,127,132,81,110,24,213,137,217,125,44,219,29,59,191,68,249,54,189,14,55,166,198,61,140,215,185,93,21,221,111,69,250,195,131,236,178,35,4,144,69,129,18,120,38,108,48,201,37,123,104,33,35,37,229,112,134,117,168,205,195,131,37,80,177,36,81,4,174,75,76,247,49,177,71,153,160,178,2,118,97,135,124,22,99,38,89,154,96,125,164,18,177,178,32,247,38,221,87,47,45,184,49,236,232,18,164,18,197,48,175,252,174,47,229,186,193,134,184,54,73,227,63,189,16,30,161,76,171,62,180,29,44,22,52,206,40,29,54,62,246,157,47,157,148,52,201,211,118,83,203,97,74,254,162,207,51,8,154,107,234,108,149,155,95,196,61,40,215,237,247,41,237,110,203,95,21,96,1,252,146,4,164,60,81,132,96,194,73,114,93,253,230,170,48,72,22,140,155,185,85,58,59,246,232,217,251,45,57,151,238,92,28,41,92,86,43,143,159,102,94,114,210,43,132,163,94,111,70,134,158,125,175,122,50,14,45,10,216,212,112,45,188,23,97,116,183,71,245,246,201,37,177,146,235,192,110,96,222,59,135,153,197,239,100,113,195,31,158,34,163,96,140,150,114,240,49,117,163,90,194,71,40,51,150,13,149,144,177,179,47,180,3,42,154,177,70,115,43,151,250,75,156,107,231,159,67,181,103,142,97,114,225,172,197,24,204,189,133,114,252,205,29,169,1,80,156,133,235,19,252,115,221,179,55,84,182,84,122,211,180,32,205,163,177,222,127,171,92,114,181,12,30,116,97,210,142,211,61,121,105,158,73,16,101,251,188,147,141,171,59,200,12,57,209,148,92,244,27,109,137,155,23,129,252,32,20,119,24,71,76,214,103,162,141,22,215,208,122,12,104,198,165,86,106,191,148,132,89,102,0,48,151,2,10,175,173,143,13,225,90,65,6,77,135,227,179,84,135,246,30,191,80,105,227,25,165,203,35,179,55,24,43,13,13,136,145,250,33,38,133,215,6,235,227,153,14,169,67,255,121,40,151,225,14,226,9,154,200,119,61,179,210,47,53,81,13,113,148,51,169,181,198,24,177,143,41,252,65,7,43,169,163,143,191,15,238,168,4,38,88,40,157,117,241,109,246,28,125,55,191,55,67,162,204,30,230,48,205,124,119,59,158,11,178,100,223,25,48,167,182,228,81,55,162,48,242,113,5,242,228,18,188,79,188,71,105,47,114,21,125,80,187,206,25,122,158,222,176,203,218,13,22,175,35,191,92,174,91,147,29,47,168,115,182,195,100,139,33,72,65,213,82,193,30,144,176,81,240,37,216,111,217,72,117,2,176,2,252,138,57,24,232,246,244,231,234,37,22,7,45,144,204,173,33,6,156,50,17,254,241,108,133,241,189,167,4,176,225,3,238,124,233,229,200,137,47,27,101,28,193,142,168,183,75,7,226,203,153,161,231,234,116,220,156,196,112,212,175,42,175,79,107,219,26,192,127,10,55,208,183,171,116,100,187,241,29,189,33,133,28,3,37,95,44,37,133,50,255,6,101,123,16,229,90,197,85,206,205,229,187,144,77,121,36,201,205,216,22,155,199,171,247,3,158,187,19,43,244,11,191,5,98,150,126,190,208,122,255,3,210,133,33,214,52,19,67,202,76,182,74,8,114,150,26,236,180,13,46,120,96,0,238,224,62,177,243,254,38,153,115,145,189,246,69,171,85,146,218,250,140,44,244,223,133,218,7,129,231,207,178,239,145,74,225,36,200,12,131,191,219,42,75,160,119,200,156,114,58,103,59,111,128,113,28,112,30,48,109,243,41,207,237,0,169,217,20,137,37,142,220,98,223,221,64,67,207,38,158,27,76,91,41,8,5,206,174,59,162,53,241,224,203,134,84,253,227,177,32,173,219,18,67,84,11,140,109,46,251,200,189,109,40,59,232,189,48,156,177,195,197,188,81,1,122,49,139,177,228,111,32,200,252,150,8,254,64,220,99,195,119,10,131,104,214,253,217,22,223,21,253,216,119,89,44,229,229,108,222,220,37,123,54,71,124,132,178,252,74,120,136,112,94,118,206,89,140,208,188,4,91,229,212,133,178,180,181,32,183,91,139,2,205,221,94,193,125,41,33,141,250,47,97,175,119,34,223,126,34,218,125,251,39,232,59,197,113,119,205,226,7,177,198,138,219,121,60,30,63,198,77,212,27,170,98,66,151,214,52,228,160,123,79,6,207,203,207,98,206,215,252,79,56,107,91,33,52,22,133,81,98,48,186,103,4,31,29,2,125,208,139,51,243,31,248,42,223,149,219,255,64,107,7,205,184,166,250,187,179,242,215,4,48,237,152,212,96,131,30,202,228,149,123,118,242,33,205,145,8,211,62,21,240,9,233,213,226,236,240,212,19,225,251,114,216,173,61,141,56,90,207,225,239,106,242,45,133,67,10,39,52,212,193,163,103,116,23,50,82,152,37,160,254,41,215,239,228,75,98,157,119,163,231,155,41,253,18,37,86,7,78,64,105,250,68,196,254,44,132,144,34,182,214,46,166,78,108,21,200,162,75,69,35,156,5,252,227,244,45,110,104,178,76,253,177,89,138,247,115,10,83,17,201,88,192,168,34,12,92,253,234,197,142,189,55,49,250,242,31,202,164,203,30,231,108,194,223,9,120,112,153,207,51,148,107,82,217,21,42,243,190,135,135,115,17,182,199,188,219,9,19,237,182,187,229,99,131,216,162,195,254,84,54,217,239,74,208,220,9,124,6,248,191,5,96,194,210,135,86,28,75,202,20,242,8,216,168,238,134,69,235,140,182,32,130,109,121,227,202,190,19,93,30,116,212,14,74,30,123,115,221,98,240,17,168,210,238,38,180,62,0,127,216,101,55,19,250,43,122,239,129,10,33,182,178,201,254,186,229,197,17,66,10,213,254,40,251,7,200,56,70,27,174,110,237,235,14,228,89,18,124,23,18,94,123,249,195,245,199,199,123,76,71,108,38,148,218,2,211,207,103,178,108,19,62,155,254,7,215,55,182,162,178,146,102,34,15,196,225,89,167,191,4,155,147,212,60,154,125,226,83,19,38,90,176,220,190,164,6,47,106,31,13,109,84,90,242,206,250,13,143,212,34,194,254,115,72,226,242,30,91,10,119,188,198,38,62,164,103,165,193,193,74,224,95,229,0,126,60,99,189,39,30,61,103,156,129,127,74,226,249,144,121,27,126,122,153,23,185,83,162,36,233,41,158,126,139,122,203,94,12,116,168,54,246,41,78,9,183,183,116,79,247,216,78,118,90,14,0,82,142,17,255,25,194,189,25,81,0,226,18,25,188,198,2,40,249,134,158,122,195,83,110,137,202,100,197,127,132,47,9,71,21,76,103,152,109,65,79,176,80,173,244,120,27,215,209,143,64,183,248,178,151,113,255,226,68,186,234,96,201,71,51,65,131,160,130,205,95,49,17,59,60,12,203,165,94,71,11,29,203,65,91,207,175,165,154,233,107,151,9,211,209,19,36,220,4,236,206,3,164,96,95,70,16,98,165,4,222,218,34,218,207,222,225,244,243,49,69,176,85,124,21,61,31,136,144,111,204,142,26,27,146,174,99,60,151,192,234,156,247,165,26,58,56,215,224,26,225,164,151,99,46,189,1,68,188,106,2,221,164,150,219,130,214,138,45,169,123,244,213,103,72,108,63,138,221,118,61,171,68,91,5,185,182,225,191,17,131,146,253,70,195,56,170,129,81,23,57,252,64,135,105,73,3,101,216,226,102,255,128,65,24,179,243,92,11,135,123,246,218,76,105,83,255,129,238,221,217,223,242,30,216,200,18,163,100,98,36,146,10,23,71,220,162,247,165,203,17,144,187,174,183,94,162,129,1,78,88,118,36,95,133,65,94,21,186,136,46,112,62,99,224,246,229,216,129,171,129,226,14,218,215,254,119,243,53,147,87,206,62,200,233,205,29,122,216,250,184,93,52,131,202,218,175,57,12,156,6,2,53,138,141,155,247,251,73,226,53,165,1,98,37,30,33,252,57,200,200,241,144,138,51,49,139,215,131,205,166,17,139,123,52,84,237,139,107,128,40,6,72,85,22,32,16,212,253,183,33,52,225,74,168,190,123,69,102,224,90,92,243,208,217,42,57,45,190,161,35,218,119,19,40,67,16,230,120,38,164,124,179,227,133,156,12,90,206,116,230,239,102,81,218,241,132,185,143,235,254,138,163,91,35,126,142,166,14,212,151,16,201,38,249,13,5,5,62,91,188,147,31,93,251,72,34,129,189,15,46,148,205,177,226,62,27,206,192,194,167,207,104,174,1,202,87,231,211,248,156,246,164,143,54,143,129,177,24,233,77,179,2,162,201,2,174,126,49,96,147,95,165,171,201,210,220,98,243,55,21,0,209,17,227,26,170,23,1,194,98,49,207,80,228,172,136,95,120,112,240,177,183,220,197,46,76,60,99,106,233,5,63,185,249,210,227,185,25,246,192,193,137,205,77,50,34,69,187,10,158,119,59,61,108,219,93,236,53,188,138,105,139,161,15,29,25,138,80,56,103,192,252,226,102,73,223,142,131,88,217,55,167,32,168,149,127,58,239,48,52,227,144,208,72,225,217,17,63,129,241,12,32,97,251,139,250,212,205,162,111,247,217,175,192,106,226,182,208,227,128,132,241,213,251,248,33,49,100,31,230,17,190,56,227,174,207,81,39,32,76,125,217,246,54,120,153,200,130,123,230,100,173,13,31,226,27,254,108,97,129,79,175,30,5,90,160,128,170,120,75,9,34,228,199,237,172,25,142,162,65,0,63,59,36,179,64,152,19,127,114,81,39,103,93,184,117,242,102,217,192,64,247,191,200,239,87,253,250,23,241,63,29,69,193,157,247,182,148,42,85,153,71,89,138,131,2,30,184,29,196,230,189,79,10,23,119,114,234,102,19,183,126,103,62,116,216,31,189,66,14,35,217,101,156,39,31,154,55,161,212,0,238,144,154,119,111,126,9,23,159,100,51,240,23,120,254,224,96,252,233,53,100,153,0,180,77,250,120,57,247,165,219,136,185,69,27,9,33,52,50,225,55,105,151,137,131,67,102,142,105,169,134,230,1,152,50,98,231,232,13,13,27,39,113,189,170,234,151,64,33,97,214,29,77,147,71,106,253,48,206,113,96,42,5,176,151,241,195,31,46,0,216,191,4,31,196,77,152,185,199,75,208,108,82,163,14,16,180,38,10,251,145,201,228,236,247,130,93,255,9,87,13,255,64,110,198,133,195,10,66,194,130,19,129,20,43,117,57,117,150,221,27,200,117,190,114,208,105,28,228,140,141,236,111,38,159,235,236,74,172,211,108,113,190,149,51,58,222,118,186,140,237,140,13,55,239,209,232,29,221,169,106,244,229,46,240,213,24,233,211,88,196,223,6,97,243,59,234,252,160,84,88,122,112,217,247,39,55,13,98,230,126,206,101,97,179,131,143,241,163,215,122,189,255,125,135,187,205,182,18,155,142,9,134,227,25,86,100,6,212,163,230,18,24,128,24,228,189,95,173,188,52,212,175,167,118,240,102,105,28,116,93,111,5,133,225,174,193,170,133,116,230,30,145,123,233,172,156,163,73,19,122,194,129,81,77,59,247,72,85,69,197,62,82,211,137,149,131,248,92,171,229,223,241,239,178,141,138,133,17,227,97,76,239,249,146,197,169,196,222,155,253,194,89,238,213,226,88,101,198,241,235,148,157,150,82,179,98,38,231,178,223,71,94,127,141,26,126,205,77,10,66,191,80,77,239,157,39,229,235,122,224,118,231,37,9,149,221,108,12,234,227,219,159,220,121,194,189,8,152,245,112,77,230,174,131,247,194,231,55,233,230,211,159,255,118,204,121,7,76,129,227,71,152,211,7,45,93,179,80,85,124,36,154,177,209,171,233,170,104,146,205,83,143,234,55,57,201,132,151,76,8,151,24,25,161,213,95,158,231,138,238,255,70,56,200,6,122,174,34,181,54,30,86,94,204,185,54,165,74,92,46,174,103,196,16,123,67,144,67,164,63,187,186,102,147,121,226,168,25,193,113,118,143,120,26,223,149,24,108,116,193,51,134,66,158,108,3,154,141,122,195,79,30,111,19,79,45,230,50,211,82,168,149,148,222,43,97,79,116,44,185,31,29,1,19,52,135,204,189,252,63,129,162,254,12,41,71,131,16,73,29,183,114,147,11,132,206,36,144,236,207,130,77,135,72,175,45,59,157,235,44,184,241,42,184,86,135,188,254,82,35,120,37,226,96,99,61,54,215,166,252,183,14,254,254,13,221,8,194,188,235,99,34,219,21,66,59,106,98,161,206,146,220,211,109,232,229,211,198,7,163,44,18,126,25,216,173,104,228,151,248,156,97,46,38,234,131,108,82,77,244,44,42,63,99,17,32,229,60,67,235,65,74,208,204,21,131,26,255,20,55,157,240,252,124,73,246,164,20,90,93,228,136,39,47,29,231,115,125,62,212,240,209,92,250,160,143,224,104,173,129,109,9,143,226,49,229,196,242,248,218,39,170,204,127,111,255,75,231,177,86,175,178,249,125,101,193,250,142,176,234,13,78,219,140,38,249,40,78,22,216,236,151,24,234,47,221,248,96,145,195,219,15,48,29,239,218,149,115,195,242,144,29,17,90,58,224,247,143,229,173,218,38,96,247,130,135,142,99,253,125,228,93,59,198,145,29,22,145,72,162,20,228,155,83,135,177,101,76,144,208,142,216,159,217,216,128,96,189,233,156,120,130,52,33,95,53,219,80,161,230,49,118,74,66,131,107,217,198,212,38,162,128,232,154,73,28,136,155,93,184,133,192,60,229,58,161,242,238,34,36,248,116,10,113,255,117,39,247,130,110,81,247,194,78,253,181,214,207,211,91,83,236,164,156,188,175,78,2,253,93,230,166,123,175,110,217,94,64,187,152,158,121,165,115,105,70,6,237,217,240,229,104,42,141,187,119,83,159,109,220,6,97,207,162,116,235,125,136,161,37,63,79,69,241,169,205,74,234,2,199,139,53,48,106,36,144,16,131,136,119,216,248,158,190,9,254,49,2,19,208,157,198,54,218,132,55,6,36,250,47,241,51,49,250,205,5,253,94,55,198,85,54,124,12,121,34,81,23,53,25,127,20,69,28,129,249,153,183,122,149,148,178,126,29,111,104,222,21,219,225,114,67,98,228,92,17,96,23,116,216,18,40,29,128,105,84,58,167,212,83,33,85,143,177,126,137,92,79,22,245,37,149,144,177,191,227,103,68,20,82,235,136,121,170,1,41,208,244,97,168,117,232,190,189,120,120,121,255,228,86,233,47,95,207,63,252,121,185,145,249,124,31,103,161,97,102,174,176,197,177,77,56,75,115,202,85,151,121,152,37,240,217,33,103,210,235,31,219,209,64,31,46,253,16,67,10,71,236,43,120,2,15,247,148,140,43,90,216,22,164,110,98,254,75,114,47,20,93,56,146,187,21,100,56,224,12,159,58,40,223,193,196,251,91,180,46,127,236,12,187,118,94,35,146,72,252,84,66,191,32,104,225,77,20,8,134,10,55,231,69,237,3,1,162,54,194,215,77,145,162,202,39,31,87,102,68,221,45,109,161,236,98,193,136,154,247,67,188,118,93,254,185,169,235,78,141,53,12,141,15,112,130,151,7,190,11,212,137,114,30,206,225,141,28,77,240,37,178,92,171,18,23,186,147,5,207,140,45,208,196,191,242,195,104,42,45,191,235,129,227,5,83,46,225,84,226,54,179,30,238,65,120,227,74,16,203,179,101,200,208,95,242,26,163,50,198,106,237,119,219,213,135,179,143,221,74,99,69,36,237,109,172,66,45,80,26,143,39,191,124,106,209,14,56,21,35,43,96,18,249,240,233,146,54,255,40,255,69,37,30,234,211,6,65,233,98,246,228,63,203,151,143,145,33,226,42,215,143,228,181,14,157,177,220,141,120,13,211,169,10,98,29,161,84,43,198,212,152,88,70,130,51,163,55,210,124,205,80,253,4,6,152,171,192,67,100,207,58,34,188,201,107,91,218,147,195,22,42,109,216,31,118,86,211,28,215,125,115,204,147,4,226,245,30,107,1,127,49,145,239,125,77,116,63,172,137,72,104,128,59,207,14,147,114,220,67,192,31,164,5,247,155,201,172,115,115,113,92,212,239,89,252,32,38,78,78,83,138,137,178,192,22,60,74,112,255,118,61,159,158,22,54,59,220,78,231,91,56,12,149,6,125,43,68,104,113,126,247,40,54,120,159,207,199,66,44,59,190,116,230,100,16,138,250,28,210,244,223,123,149,121,234,239,66,150,196,53,134,221,57,89,151,168,38,251,107,144,162,219,42,139,195,200,88,167,210,57,104,154,74,94,65,111,206,229,58,157,85,117,248,207,29,12,205,18,74,243,236,109,227,232,223,229,12,13,249,247,110,122,62,254,255,173,153,75,24,215,216,232,124,204,57,130,61,246,36,138,57,255,238,223,120,78,66,253,184,233,1,193,31,234,201,40,210,122,153,140,152,75,255,150,239,79,118,145,187,15,128,76,79,45,220,57,201,95,27,120,28,231,169,40,110,60,202,149,250,108,132,171,186,254,181,58,59,119,220,35,245,187,99,138,59,157,25,195,206,217,1,110,253,131,18,108,57,160,184,215,186,241,40,189,202,249,233,220,204,206,177,184,71,162,107,123,179,69,74,75,55,39,55,228,72,5,198,246,246,164,39,93,80,255,181,73,252,85,162,179,85,50,99,157,119,226,47,45,126,30,124,194,167,191,191,134,238,183,34,196,245,137,239,55,20,28,51,28,245,169,47,124,143,185,64,40,58,79,58,233,5,203,134,48,99,28,110,206,240,217,235,18,44,188,176,211,99,61,239,175,199,244,161,209,100,60,218,91,77,66,244,67,165,178,133,24,98,46,183,178,200,96,228,227,147,193,224,87,89,91,48,111,234,55,35,91,193,84,187,145,155,95,203,251,201,216,253,214,253,76,120,45,214,214,32,175,112,229,121,142,215,209,124,142,110,160,54,231,250,29,96,43,230,86,142,94,135,41,237,207,230,222,23,226,99,144,31,243,231,221,61,8,239,190,35,16,20,157,122,19,16,156,160,72,65,227,118,79,252,34,115,14,175,236,133,116,167,23,65,184,222,187,255,228,32,66,101,105,233,238,147,168,105,142,191,221,13,142,189,81,184,237,230,79,23,190,209,161,184,246,209,181,178,158,109,207,191,47,186,35,172,254,252,213,170,220,132,89,59,30,156,172,60,140,51,123,56,169,11,185,39,154,140,49,124,151,89,244,99,108,10,240,112,66,9,127,98,153,114,27,229,23,51,202,83,188,252,182,163,77,18,175,129,201,250,174,225,145,52,9,172,185,249,208,77,37,187,254,192,252,218,243,245,211,73,97,5,101,178,122,139,57,167,160,80,138,174,219,149,202,188,233,112,236,140,156,199,122,77,67,71,83,195,86,100,166,250,83,70,7,101,115,176,46,83,38,8,100,150,24,52,141,169,64,25,134,187,182,254,52,110,230,179,116,239,21,113,125,127,15,244,212,226,234,125,157,202,109,62,141,58,203,209,108,26,94,19,255,146,113,79,64,105,175,236,194,109,10,40,35,8,186,44,69,47,110,69,76,169,177,183,17,31,169,45,61,218,176,87,94,255,104,30,21,47,247,40,195,97,243,75,45,253,210,46,7,193,159,138,109,227,43,14,150,199,36,34,185,99,123,249,174,167,196,173,57,89,236,16,39,50,33,10,227,206,234,27,163,244,162,25,76,227,223,90,77,40,17,235,242,236,203,119,168,76,50,73,72,11,130,216,239,93,181,121,20,8,135,148,51,156,130,23,243,179,224,19,195,89,28,70,133,48,214,243,204,59,100,74,240,249,78,138,223,94,223,2,49,102,172,58,187,247,48,154,140,19,12,52,239,235,65,53,96,28,91,128,74,24,226,3,17,15,35,116,111,0,69,123,251,181,239,122,160,3,207,244,219,135,228,78,196,30,100,87,226,19,67,167,198,63,22,177,228,197,176,164,5,173,211,203,122,224,169,142,24,140,115,206,224,110,171,118,156,207,130,61,167,83,46,250,55,218,215,84,108,61,229,29,131,225,75,242,206,141,168,176,79,143,143,71,94,13,130,53,181,17,118,84,81,68,119,85,187,4,91,108,196,216,78,221,7,177,74,254,197,127,229,24,64,145,184,80,140,58,231,54,24,39,197,152,105,200,130,33,229,24,181,119,123,66,195,70,151,198,24,15,55,1,223,57,48,34,140,60,110,210,195,89,144,158,65,62,109,147,76,205,122,50,217,111,9,115,152,63,179,228,30,159,221,25,9,187,36,57,121,35,58,16,81,190,23,111,181,220,92,213,31,176,203,117,177,209,108,218,88,4,230,163,147,254,124,122,230,121,238,96,248,249,12,215,189,211,130,219,142,38,183,139,196,120,10,215,79,142,190,171,97,246,18,62,6,149,221,169,105,221,249,91,81,137,229,170,91,60,8,177,122,207,87,96,154,86,230,22,235,178,19,20,139,137,69,230,249,103,64,114,68,44,155,6,39,165,118,210,83,110,34,227,133,220,65,154,230,176,91,62,23,210,156,186,56,123,147,166,72,218,207,108,28,232,144,166,191,136,1,2,223,141,156,96,135,109,6,64,48,157,32,197,201,140,223,37,107,225,127,3,18,10,219,104,25,120,157,47,65,179,3,90,156,62,218,225,41,243,221,231,74,11,54,255,176,44,167,55,135,170,59,101,131,135,96,131,239,85,142,59,239,254,33,48,178,48,5,209,89,78,136,166,237,37,51,118,220,252,105,215,143,42,125,172,104,105,25,103,33,206,0,166,214,82,35,40,250,151,54,76,190,229,196,208,169,36,159,157,103,230,150,188,254,248,100,15,242,233,38,64,101,25,196,51,39,253,5,65,171,219,184,29,33,115,100,120,101,182,103,158,243,147,135,176,92,252,244,165,141,249,6,253,148,25,251,250,205,89,67,125,130,230,168,12,251,231,3,75,228,150,185,132,216,106,206,84,24,238,26,70,83,239,13,171,168,87,24,21,163,86,70,121,33,215,231,136,127,103,60,33,69,39,54,108,87,146,163,98,226,239,107,159,203,70,52,121,192,94,116,164,83,68,70,128,193,73,15,130,41,76,4,71,29,113,47,132,2,167,60,54,196,245,215,219,2,178,18,83,34,251,94,147,213,7,79,229,4,124,227,37,140,145,171,47,74,215,252,226,149,237,200,99,253,138,241,249,172,102,40,189,80,251,238,177,60,183,54,217,247,249,38,56,185,60,55,199,14,191,7,137,44,41,237,85,118,89,34,106,58,254,220,25,49,17,54,158,67,62,173,186,182,55,139,249,47,231,36,190,243,168,82,191,168,32,163,107,10,30,218,137,37,160,99,92,59,126,119,213,246,234,216,109,105,202,223,200,189,41,3,52,206,200,107,98,74,168,141,175,211,89,102,238,106,85,63,128,209,67,80,22,206,69,113,29,31,205,48,219,118,169,42,180,198,106,240,52,200,70,66,187,31,190,240,245,150,117,67,25,186,77,77,7,215,142,18,6,201,110,166,157,44,63,44,98,155,239,21,80,53,115,223,44,37,99,252,240,91,216,38,112,71,128,180,201,198,168,242,107,43,100,111,164,237,77,227,103,141,162,227,247,58,123,87,245,84,243,7,26,216,220,56,0,157,192,155,193,251,236,188,38,116,136,252,136,154,222,191,106,81,242,46,76,28,21,136,73,136,4,233,55,218,63,77,18,39,89,167,10,27,91,211,44,115,111,51,158,125,90,43,153,123,49,170,100,245,31,180,36,107,45,120,73,101,189,163,169,225,112,51,230,178,161,155,11,66,84,221,246,64,114,174,29,37,43,46,188,163,212,122,54,47,165,160,37,184,163,36,2,10,203,91,101,247,245,99,128,189,175,30,90,123,226,220,73,93,164,136,241,109,0,5,197,213,254,0,101,60,45,111,236,185,150,2,57,125,17,133,62,106,82,124,223,70,184,250,246,29,194,93,236,148,18,190,144,13,121,125,200,68,62,1,26,188,191,26,117,118,114,3,46,80,60,180,250,242,56,205,196,69,187,83,193,102,114,192,57,230,193,120,211,125,4,5,198,25,211,90,229,177,152,114,164,202,123,174,180,84,2,123,33,152,123,182,212,0,240,59,147,50,252,160,226,117,126,107,89,226,154,213,174,88,229,186,253,227,170,158,238,12,61,99,69,251,174,213,206,232,192,134,90,182,100,211,180,177,203,255,116,121,197,218,119,206,253,141,144,214,151,31,59,140,80,175,223,66,88,215,221,239,139,1,25,34,184,150,107,183,73,160,191,32,228,243,75,125,242,42,102,87,226,103,144,203,83,80,162,81,240,79,63,155,0,221,107,34,173,110,59,157,25,226,156,193,184,34,26,231,155,116,175,133,167,199,165,68,131,47,212,40,214,177,237,100,126,226,172,245,132,179,64,169,48,214,32,200,247,27,246,46,48,52,190,218,109,195,33,84,15,187,54,242,187,220,50,172,55,251,43,26,8,156,33,24,31,75,161,32,169,127,38,254,251,219,83,142,21,221,19,42,186,3,172,82,9,227,189,239,194,232,95,172,71,252,89,95,26,35,55,194,62,225,247,7,240,248,154,254,72,139,87,0,16,204,75,44,133,174,230,126,251,25,128,224,250,204,251,202,2,91,133,95,129,119,229,114,157,129,144,80,79,31,80,239,254,155,214,10,211,66,19,123,232,77,63,143,7,152,148,250,117,141,211,238,236,39,251,231,180,90,24,90,237,18,142,156,121,66,18,125,41,102,60,14,84,63,115,181,151,226,194,168,182,70,50,126,94,49,190,138,107,72,187,152,11,216,244,151,67,197,56,60,215,98,104,162,134,166,95,69,104,239,120,166,254,162,85,220,33,43,78,113,212,82,4,167,63,82,47,119,186,42,231,121,39,142,2,178,74,71,26,202,211,52,79,251,81,242,125,123,100,17,71,212,249,242,166,5,146,196,250,137,113,32,33,5,116,191,8,83,182,62,0,16,28,198,176,36,106,226,192,63,65,205,85,32,42,233,69,233,62,239,24,14,15,73,60,209,150,40,124,255,88,247,180,73,77,228,233,45,129,217,44,121,183,20,203,152,184,214,138,223,206,27,157,62,154,11,94,112,54,73,232,163,117,171,212,12,228,176,155,13,88,246,167,145,227,12,23,207,1,92,214,121,195,43,185,150,201,53,238,125,11,68,34,42,148,53,208,170,238,227,49,192,173,42,85,27,162,255,250,48,228,85,146,85,80,175,70,188,254,54,114,179,56,123,214,117,4,15,13,59,5,37,46,125,23,15,220,229,250,102,186,246,83,134,30,79,30,0,11,89,185,60,231,16,251,5,89,21,104,13,252,4,250,232,236,62,158,114,21,19,161,193,254,159,107,207,83,1,229,221,190,105,66,110,158,110,1,93,118,170,227,23,15,208,173,84,116,3,235,242,226,93,188,170,44,37,30,114,91,164,216,111,182,193,209,119,92,51,61,162,31,118,229,143,170,190,10,107,49,218,108,139,14,135,49,235,172,18,36,43,245,242,244,129,79,42,3,126,253,145,249,215,97,35,148,18,188,165,86,47,230,215,63,65,250,116,141,227,107,186,241,78,215,134,36,245,227,76,128,221,208,169,231,5,40,57,39,157,253,221,247,217,231,223,4,97,130,110,32,195,166,36,125,89,83,243,8,1,148,220,40,107,96,167,254,9,84,18,77,28,127,89,85,2,248,90,28,254,56,155,23,252,47,87,225,190,212,179,31,26,214,41,79,228,62,53,82,83,48,68,96,109,87,229,85,104,155,255,235,88,35,6,68,91,126,73,1,62,62,212,253,179,3,155,205,1,142,18,166,7,115,157,10,183,72,239,200,202,184,126,233,121,12,163,120,145,214,208,137,62,87,228,73,146,46,231,186,213,177,254,250,37,145,151,253,201,34,160,4,39,141,159,12,121,130,3,150,164,31,159,20,81,116,127,35,170,39,140,2,239,42,13,101,200,49,111,79,67,95,72,163,94,117,125,191,3,151,81,229,122,234,183,34,234,198,125,214,161,246,231,37,231,206,223,206,69,94,183,108,77,126,242,165,179,25,82,240,166,179,109,176,148,71,192,36,49,228,55,251,210,201,247,112,227,185,119,10,250,34,173,107,197,161,221,149,156,160,236,31,193,152,224,214,117,25,247,197,127,55,202,59,252,116,102,47,48,249,148,243,222,159,119,174,102,85,71,44,1,186,235,150,226,36,101,23,249,242,144,91,163,59,26,43,156,221,103,77,237,53,166,221,105,59,38,204,109,27,17,206,237,2,155,138,142,138,62,55,51,75,99,113,135,245,254,39,84,235,245,161,167,71,249,69,219,196,174,188,2,56,147,240,115,45,119,245,69,0,225,80,3,30,5,0,30,161,28,95,87,234,203,250,90,6,66,23,83,135,15,226,158,221,89,243,53,96,217,130,135,161,36,218,255,142,186,59,54,46,83,127,139,38,254,141,135,143,248,249,105,117,234,203,173,77,207,65,2,218,136,213,151,124,57,14,14,238,217,13,40,190,197,28,251,16,234,73,248,188,0,65,232,97,230,251,67,70,28,166,134,77,198,62,143,146,118,172,3,21,167,155,43,106,25,52,168,155,3,218,153,211,123,88,138,134,85,101,85,218,102,110,2,27,227,102,221,144,136,159,79,61,46,174,102,59,120,251,67,31,36,236,119,109,235,75,32,196,31,188,5,246,148,200,194,127,153,197,18,99,41,24,59,144,124,189,39,101,176,19,110,170,65,38,17,200,195,205,4,110,170,97,217,169,3,51,95,48,8,211,180,118,199,179,92,196,170,113,252,215,112,132,107,88,172,132,207,243,10,243,143,145,15,14,138,67,148,197,9,98,237,127,95,187,123,59,97,14,216,166,191,226,199,53,144,193,41,190,37,189,167,135,96,83,88,3,63,126,228,146,143,100,130,66,86,187,248,16,216,215,217,236,118,228,25,147,90,248,91,44,160,135,192,35,2,177,239,35,230,70,106,110,62,127,35,187,28,196,35,28,131,82,122,101,17,75,80,35,217,119,46,36,145,35,243,228,38,34,174,102,255,156,72,253,250,124,243,157,9,236,13,225,53,151,198,249,159,109,110,120,197,204,185,7,126,175,223,160,236,186,101,216,223,217,68,116,229,140,157,212,181,151,172,145,117,173,40,158,198,113,229,204,61,190,106,16,250,89,31,11,191,145,104,232,152,85,197,15,215,65,54,239,231,197,121,149,172,85,199,131,10,71,5,203,201,13,214,206,90,165,54,163,70,119,86,78,57,190,91,137,174,136,63,50,137,141,64,108,63,151,187,88,7,240,84,44,164,206,184,216,237,157,25,6,59,254,252,119,219,254,204,200,228,253,63,193,183,229,123,108,201,41,38,43,223,33,172,57,160,181,222,244,142,66,15,8,151,50,249,101,41,88,155,140,228,208,217,22,52,154,24,206,208,233,24,147,8,54,8,164,58,150,139,17,51,165,97,150,16,207,221,37,178,196,100,164,155,45,166,232,172,236,69,157,251,58,205,250,136,165,179,239,220,87,33,10,159,142,75,166,43,218,115,4,124,172,129,243,107,10,26,46,97,237,212,66,68,43,38,113,159,200,85,131,0,203,116,194,220,208,110,46,135,82,202,10,113,180,123,138,11,139,48,247,93,201,48,170,102,44,217,233,120,8,219,203,0,137,27,54,8,237,241,125,160,203,252,197,128,170,77,164,18,118,158,0,135,147,219,105,173,182,154,42,76,167,186,126,195,93,149,96,173,103,135,66,213,64,110,153,129,132,243,227,85,112,237,33,151,140,178,165,228,28,193,180,10,164,204,253,86,245,239,127,37,130,83,124,4,139,235,227,63,32,62,155,160,14,116,87,141,250,30,47,8,123,26,200,189,233,84,124,132,90,120,171,72,203,19,122,22,122,167,194,214,93,235,40,19,247,213,92,213,245,121,142,173,97,239,103,152,128,57,32,22,159,217,208,23,101,152,16,123,70,62,68,45,166,63,33,201,176,188,68,202,66,76,142,102,131,225,62,175,144,160,98,184,244,66,200,23,212,138,19,166,152,164,130,178,69,193,98,93,77,34,239,164,101,113,93,72,169,229,203,155,165,74,97,177,12,97,95,217,251,6,45,246,3,31,209,245,241,127,206,87,30,72,87,173,146,193,45,175,67,57,131,81,170,72,45,61,170,181,206,171,125,213,250,163,84,83,12,87,231,22,168,28,101,88,84,203,228,24,197,160,151,83,126,13,180,181,205,6,13,73,161,53,115,83,66,221,201,94,168,219,222,172,17,111,67,185,2,218,215,131,185,154,233,125,168,38,227,222,91,43,157,25,226,215,15,233,52,44,242,234,251,240,19,148,75,111,219,178,76,216,27,122,112,25,252,91,160,71,184,35,160,173,18,100,80,183,94,140,103,86,77,76,249,44,167,127,201,233,193,115,255,141,85,136,187,193,122,153,1,158,219,211,243,79,192,51,97,243,70,241,5,242,161,107,211,198,162,152,183,172,68,253,222,51,74,199,127,231,248,157,150,244,139,215,232,56,68,232,10,145,254,113,120,164,152,50,246,121,5,93,60,116,205,243,78,69,241,80,227,143,73,107,209,96,220,110,52,114,35,255,160,16,106,105,129,99,178,91,126,133,99,0,217,128,24,168,250,240,209,132,169,11,48,59,197,167,167,208,164,54,98,65,35,96,18,50,143,120,26,171,115,41,52,6,122,102,204,123,8,236,243,154,169,26,8,118,21,92,12,212,107,190,183,13,33,96,146,195,166,46,28,215,226,34,166,29,246,16,158,10,204,17,19,125,234,168,234,44,137,150,89,49,248,201,138,84,228,129,93,26,94,207,32,250,191,30,94,46,133,253,38,153,182,215,228,158,215,35,5,191,182,35,105,207,214,226,5,128,95,79,230,37,127,28,29,80,80,77,254,49,185,192,44,255,133,39,27,170,142,158,10,101,200,45,183,231,28,122,122,108,244,198,167,158,84,37,145,193,191,205,145,247,155,133,79,187,119,24,177,237,141,205,44,249,246,5,164,15,246,113,248,200,143,222,116,109,81,148,188,217,135,84,55,191,62,51,140,35,126,36,251,219,211,124,11,188,218,19,27,211,45,151,90,223,21,83,141,213,187,35,112,103,208,42,98,163,188,235,123,184,17,24,41,97,234,159,245,66,100,94,204,30,143,42,101,229,218,20,207,174,6,5,25,74,184,205,146,199,100,101,53,237,120,231,165,133,54,246,221,94,26,253,0,4,110,132,123,234,145,154,89,238,93,96,110,149,224,135,178,27,143,97,76,96,95,92,105,127,239,205,168,235,83,197,81,177,197,192,238,211,190,202,221,60,228,115,8,127,147,17,108,244,208,217,187,150,89,251,190,138,161,114,92,147,189,222,95,21,6,160,155,103,20,211,97,155,58,145,143,225,145,27,206,126,204,250,250,70,222,133,47,220,170,198,107,190,241,41,220,36,5,248,45,241,50,185,154,147,104,134,87,38,74,249,207,244,150,125,232,52,43,47,149,121,100,56,247,252,45,253,135,207,234,244,57,140,210,209,2,98,45,71,51,182,180,168,144,197,67,24,121,252,36,162,189,163,2,247,24,250,39,119,125,247,224,232,246,133,170,90,194,148,224,28,117,179,17,225,0,12,42,80,166,108,238,146,111,103,38,37,89,178,14,78,92,80,112,51,50,20,116,137,208,247,61,164,211,226,17,252,244,110,67,183,18,10,125,79,61,116,31,242,61,214,200,127,38,139,163,249,5,207,241,214,89,207,220,111,85,168,16,211,41,51,157,99,163,175,223,30,111,71,218,160,133,170,130,230,136,15,202,40,92,226,231,3,106,24,137,197,244,9,229,153,56,184,74,241,109,79,218,85,60,188,123,78,37,140,104,221,37,231,14,15,11,156,248,186,212,97,38,238,140,148,100,126,83,17,76,67,177,118,214,116,118,110,149,43,210,22,19,245,41,106,0,151,159,230,10,20,182,110,99,127,243,81,108,120,89,15,93,91,119,38,182,243,102,8,192,82,124,175,180,56,236,183,33,14,121,62,199,224,222,55,61,78,198,113,55,254,185,231,38,18,218,121,55,156,90,87,148,243,174,219,70,216,1,105,105,14,146,108,196,30,49,123,50,16,220,236,160,135,244,94,38,40,235,69,253,179,176,183,86,194,141,71,212,187,46,213,61,37,6,133,50,124,231,93,67,162,135,184,46,95,4,80,132,50,172,153,37,117,43,230,25,18,182,134,168,205,20,167,6,175,13,11,111,57,98,64,174,137,36,189,214,45,208,250,53,237,251,191,251,46,36,3,23,209,185,29,0,32,89,10,132,36,5,118,247,206,222,97,175,14,195,6,231,154,251,81,151,27,65,41,204,126,141,153,66,252,247,191,165,103,186,185,34,190,74,164,176,194,156,69,194,151,140,47,71,98,201,56,179,46,130,174,124,81,38,8,102,234,113,2,133,133,114,29,63,26,192,182,250,197,198,189,96,52,188,195,56,164,114,220,105,9,231,102,212,109,7,232,177,237,8,113,125,187,25,248,224,181,27,123,100,212,61,89,87,191,77,216,214,162,75,86,193,145,85,140,62,142,27,43,226,182,118,245,150,116,161,6,84,211,40,54,39,68,126,114,65,67,59,172,199,158,211,251,110,177,250,177,8,219,192,127,171,158,207,194,255,240,132,118,31,16,176,49,35,26,63,166,126,115,29,18,34,174,168,66,164,124,7,112,100,30,163,41,85,121,47,252,138,215,168,211,22,243,19,12,213,37,111,156,234,3,250,36,49,115,24,176,139,169,46,173,77,48,138,162,252,237,163,176,112,83,143,159,174,30,48,177,92,28,141,171,27,172,180,177,160,236,12,216,29,160,111,86,249,158,244,151,28,216,137,113,107,143,155,205,75,250,206,252,207,252,128,96,10,235,222,46,170,139,151,15,46,169,4,227,168,217,115,225,68,199,207,243,76,205,174,227,200,239,59,6,46,188,156,245,124,103,218,114,202,211,142,155,203,180,68,172,45,102,157,49,47,100,191,219,83,97,131,202,56,84,117,113,128,180,42,186,241,119,169,99,134,0,148,113,109,212,241,254,33,168,175,177,229,28,222,200,51,126,190,158,44,58,194,189,192,139,248,58,154,194,9,87,66,197,194,241,129,124,93,27,237,208,127,254,155,97,186,75,63,140,120,228,216,162,61,164,156,245,2,167,190,79,5,172,132,211,140,89,84,152,243,50,26,112,213,33,118,61,207,46,33,87,100,68,205,27,207,79,142,107,190,108,23,172,240,221,16,44,68,210,167,35,163,58,21,199,21,63,80,235,44,241,25,87,43,163,179,95,159,246,161,205,109,123,181,221,85,235,35,172,225,35,142,140,51,129,205,134,128,97,143,176,125,193,7,74,101,34,153,165,142,230,216,164,87,125,202,242,9,145,82,213,120,25,107,252,58,39,220,135,25,26,226,63,195,247,3,154,127,11,89,109,117,157,221,213,65,221,5,202,255,161,110,201,113,182,14,171,82,58,81,158,68,248,7,221,245,252,241,63,26,222,50,168,234,239,255,250,166,187,91,58,5,9,81,145,70,14,13,18,2,210,221,37,74,119,29,105,144,110,16,105,233,238,230,128,210,33,32,37,221,221,125,14,39,62,247,124,127,247,255,154,245,108,207,236,89,243,218,107,175,217,239,71,219,124,148,3,59,125,255,93,219,249,137,132,43,122,65,131,182,141,40,110,19,194,46,121,127,253,193,205,141,38,165,96,255,211,23,227,46,64,251,254,161,157,10,197,141,164,182,112,189,158,255,36,120,176,213,224,133,36,76,124,82,154,253,48,118,19,23,242,183,226,83,201,186,199,123,212,167,34,215,233,130,19,92,163,93,231,214,236,188,100,123,101,234,3,250,74,31,74,19,83,231,24,97,149,19,209,207,150,220,255,232,53,74,183,52,241,49,63,190,230,210,155,86,103,137,63,158,47,203,12,101,111,116,85,246,159,123,103,129,234,195,101,180,189,25,22,36,114,211,120,76,206,116,38,98,90,187,141,161,30,39,13,113,61,2,102,125,46,154,249,88,48,6,124,204,253,42,25,84,32,180,167,65,239,128,205,145,218,160,61,239,99,108,204,245,243,171,64,201,173,106,108,105,175,39,143,39,221,71,76,196,198,151,253,71,243,120,58,114,112,39,7,24,75,233,57,93,144,234,0,11,111,30,223,83,146,112,91,215,119,196,35,168,171,220,196,56,219,63,133,103,173,28,5,160,11,165,16,29,217,236,18,246,252,65,109,9,248,110,20,12,64,222,188,145,198,122,250,146,196,211,87,20,3,126,16,82,35,50,79,12,96,38,246,95,37,64,170,227,216,202,32,187,5,207,24,202,223,35,244,251,120,235,2,225,19,194,119,36,210,84,55,81,45,188,97,191,98,102,104,30,18,104,189,153,14,111,251,10,14,31,214,191,152,92,245,70,73,30,254,82,91,147,73,244,55,245,175,13,28,90,21,165,120,125,204,148,120,250,229,88,4,201,52,34,245,170,46,26,87,223,226,67,193,69,166,231,164,77,251,59,179,195,151,65,179,12,57,41,60,224,100,73,40,159,42,228,122,93,90,73,230,203,16,88,111,213,181,138,2,60,253,238,150,197,119,226,222,160,153,6,90,137,81,147,234,250,226,16,21,122,173,143,162,243,243,157,148,44,232,72,184,110,234,197,120,153,238,2,14,198,176,149,100,116,166,37,253,93,175,162,101,204,87,238,115,222,117,65,20,79,109,18,104,183,87,47,154,169,212,241,205,102,168,134,24,165,39,249,153,4,23,199,217,143,33,237,37,228,203,106,162,159,59,137,224,170,31,194,169,6,186,209,253,181,90,78,244,62,23,251,251,73,179,67,253,198,133,81,162,133,31,194,44,96,32,231,226,193,164,112,68,210,203,141,240,213,7,105,204,128,181,97,65,31,31,135,173,80,178,9,219,109,61,59,240,20,78,172,105,198,143,106,134,7,108,79,105,195,221,162,90,247,66,197,69,45,155,48,254,227,163,102,127,247,208,107,232,174,55,10,143,119,104,215,27,92,103,24,51,232,71,52,57,71,97,149,4,85,37,77,62,185,85,253,74,24,141,193,236,179,44,88,144,97,105,89,154,106,198,58,204,147,250,102,209,234,217,113,123,13,191,38,129,67,74,207,121,211,254,153,105,179,253,212,218,151,71,20,230,173,130,139,67,16,215,45,213,38,141,124,93,210,208,140,208,126,90,173,169,201,62,221,180,124,181,230,22,168,60,135,143,34,89,147,77,105,43,131,121,228,252,122,239,113,7,232,54,38,77,147,131,49,206,108,253,242,9,250,157,169,35,113,101,149,156,17,102,230,237,8,110,90,21,157,33,128,62,198,60,175,191,161,7,248,6,44,250,101,113,0,91,60,109,206,225,24,204,161,227,246,184,244,83,206,214,226,242,63,217,161,251,225,61,33,144,105,244,139,239,16,84,48,54,172,62,161,157,49,241,194,183,167,216,126,220,215,5,0,49,158,44,154,181,191,206,49,255,137,48,123,128,246,58,175,182,229,141,179,87,200,195,14,230,254,61,43,87,233,129,222,84,223,139,124,191,81,128,77,100,190,164,30,134,29,28,123,169,219,141,68,203,22,213,81,180,255,93,129,24,194,58,127,2,42,104,47,202,164,105,246,37,68,245,15,90,80,138,37,100,230,248,64,237,56,179,167,21,109,76,163,136,221,90,198,88,65,19,222,123,185,144,181,102,86,68,208,237,201,221,35,252,34,201,155,2,213,23,134,20,63,27,149,174,123,233,37,144,86,225,83,101,25,218,167,203,87,137,48,123,248,71,248,39,0,119,232,3,55,27,77,240,71,223,101,234,165,213,121,175,204,202,155,131,37,39,215,120,134,221,141,145,223,126,18,58,227,171,89,93,97,168,49,109,68,229,95,115,212,13,9,184,66,52,87,222,245,222,89,243,179,17,230,62,33,160,167,185,240,142,116,31,52,4,110,13,143,192,205,77,143,255,185,159,212,190,44,245,51,199,130,215,148,84,242,227,15,148,4,180,233,169,34,100,132,91,130,203,182,19,64,111,224,200,126,48,120,19,37,21,6,188,144,252,91,151,87,124,157,143,49,49,195,82,183,149,61,55,105,230,181,220,218,196,81,132,40,109,224,96,217,77,248,227,190,107,169,188,197,39,144,85,63,184,194,158,128,228,171,254,177,8,121,129,106,110,130,125,2,102,20,42,2,23,118,11,116,82,8,180,182,56,86,223,185,222,23,36,127,250,121,148,76,164,216,96,134,38,244,64,144,76,116,213,85,131,74,210,180,205,73,49,83,188,105,155,120,38,25,239,201,18,234,49,53,112,91,242,196,124,201,103,191,127,251,16,98,120,232,202,4,141,24,130,23,116,111,151,50,51,188,85,155,13,35,208,202,36,236,208,199,90,137,155,43,48,245,123,134,227,1,181,143,190,24,224,54,109,155,15,142,8,153,102,128,202,5,211,7,201,61,132,83,113,146,73,89,27,191,111,251,222,45,117,39,68,168,22,209,139,16,58,167,64,202,251,212,184,195,229,249,217,45,112,206,59,173,100,245,244,164,199,213,198,15,101,249,33,147,8,220,118,254,151,190,251,3,22,191,220,57,213,175,11,150,95,84,32,221,9,225,189,51,184,221,223,117,218,183,57,19,32,18,222,159,186,57,224,204,89,47,44,240,9,103,112,79,241,87,241,253,127,119,126,255,59,1,218,175,213,232,126,24,127,27,46,246,188,88,186,197,109,89,111,105,121,222,171,242,230,112,252,146,233,244,121,47,188,141,25,39,178,131,93,148,11,216,47,102,137,189,213,7,2,190,123,38,132,56,127,105,33,97,224,41,184,43,168,127,67,174,146,111,140,124,143,73,18,43,47,169,254,16,255,139,245,13,23,57,187,111,233,141,195,117,14,27,229,83,136,168,224,155,45,227,209,180,242,59,189,250,110,242,211,109,234,57,72,235,233,124,88,15,83,193,32,177,19,73,127,246,136,132,223,108,133,24,202,247,214,134,185,37,129,136,17,176,177,14,108,249,12,189,28,116,239,157,168,119,23,238,13,182,233,41,109,113,77,123,85,39,122,64,45,26,252,109,89,180,73,214,111,110,35,59,213,25,202,247,1,52,118,32,168,1,218,165,19,208,227,7,170,226,174,193,122,231,73,21,65,73,142,145,15,130,117,224,72,189,225,214,131,43,73,45,245,226,47,28,136,84,84,217,212,247,110,200,230,109,195,42,129,14,33,77,121,193,46,45,35,223,75,10,178,88,82,201,33,16,99,52,138,116,238,225,20,28,86,92,69,199,188,109,221,5,252,110,18,236,189,9,224,23,15,123,17,236,63,173,140,56,56,93,190,72,16,45,28,121,29,114,61,71,106,37,97,177,214,2,158,72,115,135,217,200,14,93,89,80,32,157,128,250,187,7,193,1,64,151,141,247,77,185,168,255,181,12,79,133,80,11,45,253,15,61,18,156,188,218,10,29,113,210,95,111,159,77,251,249,60,27,121,30,131,152,143,151,217,54,1,136,38,249,90,82,202,208,173,48,76,183,188,67,168,101,118,107,241,254,29,191,239,126,232,72,45,189,129,225,11,57,167,235,26,143,172,53,88,119,156,8,196,138,133,223,114,162,120,143,234,67,13,190,242,91,76,204,248,9,216,243,144,126,152,109,219,173,11,220,250,50,63,177,158,221,14,242,193,101,142,16,124,155,252,203,26,154,254,79,216,229,47,29,225,247,221,132,128,141,235,172,246,229,16,238,114,88,253,192,196,14,226,50,82,243,131,230,51,191,252,106,163,102,251,152,58,130,249,33,19,229,80,128,219,26,117,118,24,157,224,110,118,253,158,85,114,62,179,54,99,114,20,145,222,48,221,136,105,202,77,84,147,134,106,237,68,190,151,98,235,124,131,72,225,14,5,246,82,161,173,223,30,12,232,237,38,75,206,118,33,133,133,207,63,145,175,252,123,80,156,165,185,224,10,182,39,55,54,134,159,34,29,110,254,116,200,178,83,91,244,12,108,119,249,157,122,220,214,173,223,69,45,167,77,147,250,146,34,79,157,38,253,87,10,21,96,160,42,87,240,207,209,244,233,154,0,247,109,203,54,181,215,136,133,33,203,129,117,82,128,97,238,118,139,248,143,245,254,18,238,240,152,135,189,98,60,8,55,254,182,217,224,183,88,37,169,29,85,135,82,182,113,10,97,149,75,88,104,152,94,43,248,207,14,139,170,1,34,154,232,48,13,69,236,90,157,30,5,106,3,163,81,90,124,54,162,6,8,161,93,118,207,99,153,108,76,176,226,76,92,176,249,31,60,52,201,227,128,144,225,5,74,253,228,68,186,95,73,55,154,189,190,172,94,181,216,27,91,186,30,146,71,213,51,169,123,144,151,204,246,27,200,25,200,21,236,221,230,115,165,6,78,137,61,93,163,249,41,1,227,86,15,121,37,72,100,61,248,165,236,97,87,202,5,118,13,238,147,120,235,218,235,17,212,251,103,116,92,163,49,232,221,59,208,195,224,245,169,98,84,10,93,35,133,126,74,79,27,240,73,232,70,92,13,53,178,242,49,4,106,108,148,140,246,246,223,216,139,56,192,225,178,139,67,182,56,215,127,242,235,143,171,205,138,235,46,151,184,58,147,206,112,214,110,77,105,209,181,119,136,203,242,251,153,54,78,224,214,209,171,73,30,38,141,235,213,99,165,156,44,106,39,5,5,73,29,98,254,236,102,14,48,109,114,118,82,191,201,174,147,182,53,64,23,69,121,173,60,187,232,220,222,48,40,46,137,43,132,174,109,209,6,113,213,206,141,170,245,92,52,243,18,34,39,57,142,88,236,179,121,101,97,135,197,136,180,193,84,104,253,196,66,104,136,8,197,177,237,234,53,233,33,204,22,140,63,67,239,215,221,193,179,34,229,184,28,67,192,254,225,33,186,28,251,237,96,7,149,138,96,37,242,126,161,157,139,68,156,211,129,63,78,122,233,178,237,167,38,158,81,166,38,52,158,80,218,196,29,57,17,221,205,43,184,0,16,204,13,21,209,119,56,4,191,31,55,60,239,74,222,199,157,226,158,127,103,193,155,116,42,92,200,159,139,40,240,90,49,186,136,180,170,255,196,171,242,20,54,116,76,218,180,230,148,166,33,128,107,155,172,121,147,213,66,252,73,208,84,181,49,57,157,250,158,197,63,151,16,233,90,141,251,201,48,225,92,112,132,234,159,18,219,140,15,111,13,6,88,196,90,62,29,222,47,66,60,242,175,62,92,250,223,165,165,228,11,87,192,63,36,2,62,178,155,46,154,22,189,115,190,217,125,249,85,87,149,217,58,64,233,110,64,245,23,104,137,190,27,206,54,202,80,198,243,17,224,248,169,176,205,232,192,250,2,241,203,245,234,232,26,26,176,61,109,72,235,111,54,200,183,2,88,167,186,248,161,183,177,244,141,39,61,8,182,95,185,210,221,88,86,165,64,118,65,55,239,223,137,168,253,178,48,6,150,34,222,113,30,104,220,245,80,89,101,13,131,130,245,112,214,247,113,32,111,81,48,140,83,154,35,7,230,136,250,147,252,160,80,27,102,32,28,185,141,134,252,246,180,20,180,160,27,18,227,169,192,194,208,241,200,229,56,114,3,11,139,8,90,208,168,45,200,121,105,129,84,183,149,7,118,7,117,166,231,179,149,219,47,126,188,142,124,16,160,84,121,86,158,63,215,193,12,178,115,88,63,238,112,44,48,129,234,148,26,122,207,11,76,1,50,90,133,106,130,81,50,254,186,165,192,16,174,11,111,1,3,226,239,185,235,161,83,126,201,180,118,218,151,30,107,56,95,221,33,100,123,190,65,139,83,248,102,228,85,221,42,153,142,238,101,7,223,240,55,193,142,201,132,60,104,163,228,214,86,62,143,216,46,128,245,4,227,250,135,194,101,78,181,29,224,117,137,107,180,174,203,80,103,202,189,0,26,16,230,193,137,158,229,36,82,44,222,10,108,21,54,120,34,83,162,127,200,202,237,170,51,93,102,142,68,133,109,126,73,16,47,234,81,29,76,4,22,163,231,214,22,142,116,222,133,191,188,237,154,174,226,125,2,233,147,83,231,205,49,88,102,104,36,119,23,153,44,213,93,32,73,165,251,191,46,125,184,128,8,38,42,52,203,217,145,25,61,8,162,109,99,64,243,186,250,229,193,239,201,227,54,63,108,142,188,35,38,248,138,61,46,57,69,16,246,236,25,219,183,214,242,116,3,126,200,91,212,163,132,159,43,127,58,162,75,12,143,166,155,193,165,27,215,117,134,137,123,131,218,41,159,10,0,35,174,113,69,169,111,125,167,115,31,153,152,121,133,221,77,16,117,185,206,51,13,69,55,201,111,174,17,22,61,110,41,7,6,121,239,156,203,156,49,34,255,82,220,106,184,116,108,43,213,233,215,174,228,12,219,23,69,120,242,2,39,51,40,66,26,196,142,136,235,146,177,148,228,253,164,231,154,34,224,171,49,8,178,148,153,172,29,123,96,137,22,156,123,98,70,225,94,231,48,252,9,132,175,12,106,138,9,165,80,235,99,160,50,183,167,206,4,203,53,60,231,202,53,209,245,157,59,137,69,62,135,139,118,137,142,181,144,110,127,243,250,215,169,104,56,109,183,146,62,102,248,25,170,54,121,185,50,216,250,169,21,125,241,253,10,217,169,55,250,110,124,114,249,211,97,88,40,119,55,32,125,157,189,40,5,183,197,161,209,214,156,112,248,134,170,0,135,151,36,181,217,27,198,34,197,49,186,30,190,212,59,63,187,31,54,185,28,202,194,29,97,39,126,246,13,124,246,109,183,160,96,123,26,141,198,129,44,46,91,194,57,60,33,84,81,204,10,29,236,132,186,21,24,27,43,208,28,166,117,134,12,44,127,138,244,95,18,117,155,106,216,106,221,241,179,99,222,202,167,162,121,153,254,49,196,67,50,24,66,177,10,12,29,22,248,56,32,240,165,100,253,78,134,200,93,36,107,32,156,15,186,218,176,33,152,197,194,221,200,205,242,205,86,87,86,164,233,54,208,209,88,178,254,186,129,227,249,121,164,189,242,43,59,249,43,39,35,103,236,183,150,87,32,241,132,147,172,108,222,111,22,112,172,229,243,249,49,9,173,161,125,215,107,107,168,106,26,196,205,194,106,124,86,169,129,195,212,193,49,24,170,138,24,23,222,97,249,92,247,252,6,16,40,211,95,177,191,125,8,251,219,73,107,81,247,34,213,26,94,191,252,192,2,63,113,92,186,140,137,215,236,24,136,98,232,118,191,12,57,41,183,226,60,53,152,7,77,100,201,103,238,83,126,88,32,116,103,24,32,241,45,228,15,76,40,196,217,197,185,1,86,119,34,93,8,130,229,248,127,174,253,116,210,89,162,104,234,217,198,57,122,220,114,142,45,156,254,54,1,185,83,193,127,0,13,78,139,160,92,123,175,63,249,142,8,44,197,173,248,130,10,246,191,135,190,212,109,87,120,10,71,233,96,233,74,21,32,146,28,193,248,59,212,215,16,9,104,224,23,162,61,129,5,220,85,180,224,6,247,203,160,248,143,51,248,106,104,137,191,169,80,78,146,14,147,175,32,237,246,9,198,134,209,255,16,230,173,164,59,141,210,232,224,77,203,224,186,49,139,160,50,239,207,38,109,159,19,238,53,69,220,52,114,69,219,241,200,193,226,92,96,65,41,228,79,6,63,85,112,216,228,187,119,142,45,167,141,235,15,142,220,34,142,179,15,14,187,77,181,215,44,72,150,164,71,5,105,132,184,207,98,155,173,61,158,37,125,240,130,237,36,38,81,122,112,46,244,197,176,20,116,107,30,154,131,151,11,105,224,255,178,249,234,160,145,124,88,106,197,115,242,247,136,230,4,176,163,120,165,87,222,111,48,212,97,206,209,163,251,71,120,100,105,211,77,30,86,197,119,10,84,37,168,189,176,120,12,202,173,94,64,186,191,223,167,100,112,130,57,252,224,252,138,250,246,175,192,74,222,220,163,156,209,151,170,217,39,9,249,168,216,126,122,1,73,130,98,218,204,33,46,189,103,46,95,235,75,49,51,90,11,86,160,217,12,249,238,150,118,216,80,151,191,69,1,119,115,73,127,167,126,40,53,190,14,194,73,160,22,237,55,116,71,243,252,136,182,168,158,119,155,177,232,183,47,97,84,251,42,100,150,224,244,173,136,107,162,112,90,80,96,52,103,198,44,138,147,125,172,128,155,231,182,89,19,228,1,63,79,60,86,117,15,154,126,247,216,161,243,65,156,139,77,40,139,228,47,101,213,225,199,222,212,46,173,10,34,174,79,95,24,61,166,209,150,200,48,38,52,59,62,109,105,94,226,170,156,174,6,51,87,221,139,27,198,21,86,143,198,11,58,9,105,238,87,11,20,124,219,33,50,46,138,162,120,209,181,241,64,98,164,98,115,212,20,186,100,61,120,51,135,96,73,170,124,127,247,74,69,253,55,173,188,70,110,119,56,233,192,90,185,117,208,49,194,53,172,29,189,107,183,89,238,38,91,110,111,185,7,3,128,41,77,219,103,43,7,54,11,180,181,12,223,82,208,174,22,100,223,177,114,223,222,81,99,236,99,140,12,122,15,66,88,185,232,82,153,196,88,39,137,62,173,101,106,160,150,201,123,9,9,25,203,195,203,222,233,130,126,122,33,117,154,245,53,150,250,116,184,145,134,142,195,48,203,15,138,19,245,22,237,125,171,140,167,210,87,35,245,26,234,94,252,137,25,185,245,79,35,60,108,218,212,251,224,144,185,203,85,10,141,206,231,71,44,192,83,246,228,111,214,134,54,39,202,163,21,249,235,253,178,194,29,237,223,102,175,97,135,140,87,76,161,67,36,80,35,83,206,45,48,254,67,189,222,41,241,246,15,215,81,245,55,133,67,238,210,203,22,169,92,108,59,249,232,112,225,1,32,217,104,5,165,8,96,254,98,66,10,166,81,203,213,98,193,210,120,172,60,151,190,128,247,217,108,182,163,135,154,146,64,232,62,108,251,192,214,167,25,32,106,27,131,136,113,201,227,92,210,103,80,144,163,187,199,32,21,224,176,56,246,53,155,50,32,248,250,56,20,57,231,5,227,26,3,95,223,228,252,184,159,226,134,9,214,1,163,23,39,138,160,239,234,98,186,187,248,46,11,113,33,34,29,179,47,171,59,162,86,193,226,17,123,117,171,46,233,234,51,32,91,177,131,8,208,251,76,111,37,116,129,34,4,70,207,177,170,184,203,102,37,7,54,93,37,255,151,247,200,105,9,195,164,152,224,252,169,45,74,99,92,252,107,1,207,126,73,16,28,194,217,207,19,37,61,32,59,15,178,148,99,4,27,238,67,9,221,61,150,106,193,25,63,34,137,203,41,171,66,141,184,8,26,245,45,157,80,184,112,75,38,86,87,38,9,175,241,59,72,15,145,182,108,217,117,59,51,206,79,24,225,195,116,132,198,138,188,7,253,185,69,20,237,242,18,200,145,66,55,90,144,167,132,58,88,199,8,169,122,11,41,70,10,137,224,163,254,254,82,188,102,217,251,6,141,182,236,144,20,63,144,205,124,131,30,50,114,7,122,255,144,192,93,218,10,9,210,235,217,98,181,16,126,101,10,171,61,2,47,148,6,255,254,62,214,226,62,6,101,217,121,169,108,196,155,185,239,49,163,192,150,132,152,238,127,171,207,4,210,70,51,198,144,84,201,124,221,234,133,18,34,54,139,233,249,9,210,237,195,2,14,137,227,45,212,253,110,137,223,160,161,91,68,108,151,10,215,189,215,75,5,210,202,10,174,3,62,119,135,59,48,208,53,83,0,229,247,79,116,144,126,181,26,252,223,70,186,52,176,233,29,163,62,183,194,180,181,181,61,20,38,27,59,251,171,191,45,61,29,170,118,10,7,127,233,248,163,159,167,252,145,49,205,231,232,130,225,196,23,57,75,141,52,230,25,171,169,192,89,73,205,126,71,57,65,109,222,254,28,83,231,179,140,189,115,226,112,125,26,31,188,33,92,11,247,221,76,172,172,11,232,232,244,60,236,128,152,250,176,25,29,193,44,142,112,126,120,72,244,221,25,225,158,221,124,0,239,129,247,183,53,71,169,225,67,224,124,130,17,114,160,58,18,114,189,107,225,105,49,157,95,59,244,128,122,220,131,172,157,214,39,92,171,31,232,122,106,172,189,198,252,64,3,41,65,25,117,162,238,205,53,246,183,33,244,71,0,238,101,231,111,239,245,174,104,184,253,133,193,133,96,150,133,173,216,221,205,58,144,46,100,26,238,125,85,166,222,2,222,64,249,33,179,94,47,109,81,17,119,27,82,81,113,61,204,162,148,129,232,108,86,173,134,195,164,87,70,191,81,155,38,245,144,131,131,201,156,93,17,151,57,28,11,85,212,68,111,232,253,118,140,34,205,63,186,57,16,179,100,255,6,77,117,205,205,241,137,18,144,69,76,40,157,60,70,180,208,15,136,134,17,127,90,209,23,122,42,189,93,114,3,118,167,174,109,214,151,252,224,233,58,78,64,82,147,122,193,204,196,155,114,15,201,54,144,173,209,205,240,196,240,21,15,120,232,142,212,110,230,150,127,148,77,49,53,139,79,30,80,66,209,238,130,114,242,184,159,46,167,68,135,141,88,106,190,152,52,231,213,247,126,183,140,214,145,252,184,145,137,41,126,103,83,12,152,244,14,67,176,176,142,141,165,126,88,194,41,113,197,84,238,84,230,33,230,207,199,95,2,174,81,175,73,199,87,211,146,114,130,75,186,250,167,135,165,94,217,137,121,41,51,2,233,222,180,27,223,146,0,188,175,109,41,223,23,210,221,23,130,16,183,33,241,22,142,53,116,200,66,136,105,212,53,225,177,243,5,193,58,126,249,143,74,163,162,163,220,250,218,135,205,25,57,226,140,85,182,67,22,188,107,89,117,130,119,101,87,3,122,33,227,35,167,31,1,137,116,69,180,66,183,95,112,57,26,210,243,46,227,176,199,116,150,212,239,216,141,121,73,114,199,118,137,99,61,153,241,117,21,210,24,62,111,196,198,113,24,134,134,205,163,105,202,37,50,192,231,25,180,12,224,126,124,66,71,226,171,6,141,213,135,58,32,182,60,214,63,5,96,150,252,133,39,146,241,21,68,255,227,45,16,249,20,3,44,12,111,66,27,109,214,106,193,189,56,53,118,12,244,73,222,88,27,230,110,99,212,134,98,217,113,95,119,37,92,97,62,181,31,110,52,251,210,99,67,98,209,242,124,94,141,199,201,207,67,134,241,114,138,250,211,50,254,21,56,215,117,24,178,255,169,136,253,48,164,189,234,115,94,232,44,94,200,120,35,36,165,4,167,205,254,180,131,127,23,235,41,251,129,3,133,97,78,113,132,38,55,11,84,18,1,151,9,238,45,28,75,223,99,198,245,233,168,26,189,15,205,60,74,157,241,36,139,201,96,130,113,20,72,87,35,189,23,47,85,43,153,15,200,89,197,94,184,2,225,99,120,157,133,216,37,168,91,159,162,48,36,68,212,130,225,20,165,100,244,96,170,7,167,11,95,135,129,251,198,133,213,123,179,7,30,84,63,183,238,49,231,170,94,1,122,25,82,55,160,161,128,105,33,204,86,52,85,55,101,24,55,238,76,166,53,233,182,220,79,236,201,173,159,61,55,5,151,80,134,36,220,186,166,60,197,61,13,83,247,67,139,128,72,19,223,117,239,87,98,121,41,213,255,0,12,193,81,18,130,103,168,219,94,228,194,223,210,109,139,39,140,183,97,230,132,201,12,166,213,34,119,106,38,244,189,3,117,53,47,145,233,237,171,175,14,82,26,116,227,75,165,121,223,250,59,255,83,65,36,238,214,239,105,189,216,101,97,78,88,123,157,105,171,53,219,136,111,88,87,8,164,212,63,1,198,137,22,217,43,127,206,6,114,19,86,91,125,71,10,34,26,173,163,90,255,161,156,17,3,115,130,129,118,84,135,107,139,224,153,12,207,123,85,94,5,230,143,63,121,116,109,57,247,71,25,85,153,183,230,228,240,179,135,216,183,16,41,155,158,18,226,17,110,41,55,42,3,123,73,238,254,102,139,88,180,126,164,229,107,183,109,78,239,206,50,250,235,134,110,226,174,11,62,19,244,112,77,247,119,14,251,57,31,90,241,127,92,114,52,123,169,206,12,179,40,133,170,245,159,54,50,194,32,198,55,154,239,44,175,50,149,88,251,199,172,150,112,9,227,153,87,1,219,60,5,164,60,137,63,215,215,60,144,42,84,9,129,123,49,155,19,251,180,36,20,209,195,222,60,238,8,38,211,25,240,115,90,85,50,84,59,151,229,239,159,80,148,163,86,221,6,255,229,81,209,207,131,186,154,135,55,62,127,85,47,49,171,57,86,253,17,78,121,157,21,67,175,40,185,13,73,244,254,244,216,59,55,127,217,65,105,165,124,53,204,37,204,105,151,118,125,70,22,8,102,123,42,216,35,88,198,200,164,186,5,185,191,94,177,40,30,158,25,206,3,221,192,109,197,146,249,169,40,75,80,66,210,49,6,182,250,207,206,93,195,64,55,218,142,243,178,127,129,99,53,35,105,244,185,227,127,251,17,128,54,16,198,22,250,66,215,9,1,35,244,49,250,33,252,57,213,87,108,63,163,2,24,228,177,201,110,44,53,62,1,5,190,125,174,64,70,109,126,67,144,183,71,28,220,80,1,188,80,52,239,111,184,85,14,129,100,194,193,131,242,81,94,228,22,181,71,209,134,53,238,8,238,55,81,152,88,187,229,99,12,229,113,28,144,33,79,38,93,57,88,225,251,191,125,250,80,72,62,24,61,157,181,102,5,110,129,149,65,187,50,76,7,217,50,188,238,10,98,75,236,153,237,109,173,68,170,205,64,10,27,149,136,253,35,127,138,28,202,93,44,78,54,127,27,15,37,225,100,194,132,27,199,168,103,142,207,124,53,70,231,206,181,181,116,208,254,243,206,106,200,105,239,115,253,221,191,43,117,210,12,214,148,128,111,117,156,82,127,6,117,30,99,41,170,21,98,10,197,244,165,111,147,246,25,104,49,129,165,93,198,132,61,106,57,33,254,158,127,205,6,44,162,30,107,146,117,115,101,185,138,168,114,55,187,188,66,213,225,2,225,112,78,174,29,240,212,40,184,122,241,180,211,94,192,56,166,188,245,21,169,55,237,164,119,32,60,24,240,90,218,68,248,186,231,106,48,222,39,25,160,241,205,65,118,10,47,87,20,145,38,108,240,185,128,222,251,222,8,201,165,30,69,79,95,58,175,115,158,163,21,13,9,239,182,83,190,93,208,247,10,137,21,208,45,125,188,79,175,17,246,203,153,7,101,184,235,27,103,204,179,89,128,77,110,52,101,252,6,48,110,53,158,110,117,156,37,224,162,234,248,222,234,220,249,39,215,245,165,164,199,148,6,56,9,229,48,174,89,197,143,50,136,5,50,38,158,178,70,229,185,127,32,18,158,92,239,239,192,19,139,181,108,19,2,182,158,206,86,3,103,47,115,191,176,25,245,101,54,17,17,249,57,83,194,65,47,58,205,101,81,65,229,175,103,59,51,106,192,6,60,5,180,100,197,200,9,228,117,18,77,236,185,215,135,155,54,24,205,69,34,28,216,174,235,61,126,16,67,233,172,195,11,40,172,99,155,198,60,230,33,150,81,176,91,106,38,224,103,176,243,70,113,105,182,170,255,41,17,220,103,36,56,73,102,3,197,60,2,178,155,27,127,131,34,90,45,238,56,211,153,121,108,210,175,252,131,202,26,254,182,15,182,158,178,137,167,102,241,177,181,16,221,105,245,53,29,249,147,139,223,28,43,40,99,31,235,20,198,26,189,158,66,144,61,44,107,158,4,57,101,163,67,186,166,202,97,120,10,237,33,210,221,15,90,74,201,41,36,46,159,59,70,16,174,209,215,194,228,245,70,109,100,85,212,69,135,225,184,169,17,25,18,74,139,84,84,154,12,111,8,58,249,130,99,106,124,157,27,91,232,25,102,14,43,189,58,166,161,170,37,103,213,174,48,215,62,208,178,128,113,203,168,128,113,211,168,240,64,150,44,209,14,53,212,122,46,59,86,150,2,99,35,14,81,47,133,240,55,177,67,112,215,115,160,34,149,118,94,198,120,249,95,47,29,254,67,37,66,176,111,105,11,133,62,174,46,84,154,40,135,105,46,82,44,47,214,215,244,221,88,248,60,21,81,147,229,20,228,120,90,142,203,205,67,246,27,65,174,125,160,33,1,243,30,60,200,80,157,118,201,240,47,150,205,3,86,146,74,207,206,3,38,113,134,207,122,233,224,93,162,70,165,81,106,26,254,36,40,166,96,49,66,175,23,117,28,188,134,54,178,25,6,187,53,59,55,246,54,61,151,104,224,72,158,191,25,5,25,39,106,209,100,99,54,77,212,129,5,94,120,198,156,91,220,159,179,168,155,103,220,110,250,74,105,0,138,240,238,231,208,205,195,108,74,70,240,45,219,132,247,201,188,79,171,243,82,202,212,190,37,246,109,210,131,65,254,235,59,245,153,143,31,141,62,202,132,2,178,184,199,140,140,66,102,142,244,47,107,14,163,30,29,221,223,61,64,240,171,190,190,120,77,254,139,81,204,132,233,14,204,242,79,227,207,104,195,214,18,172,142,102,175,150,100,47,65,150,103,23,135,232,27,202,245,254,14,88,126,98,163,218,170,13,52,121,52,25,53,172,68,53,190,157,5,120,199,0,162,135,47,3,24,241,254,243,117,248,12,202,254,105,20,55,159,171,205,159,202,173,159,104,107,110,250,104,115,104,204,101,136,30,166,133,40,140,110,5,75,214,253,193,95,90,193,187,32,232,47,129,97,195,107,215,56,240,111,99,221,31,179,131,123,73,129,105,255,90,87,81,158,8,116,213,88,64,156,201,3,21,154,156,79,240,45,150,89,44,157,30,11,95,19,131,55,70,79,38,227,98,171,111,103,91,13,221,84,147,94,118,41,57,233,135,111,217,128,187,21,49,62,23,135,64,116,179,30,102,32,165,234,91,214,192,143,250,100,170,182,48,50,203,125,242,151,184,90,6,155,55,167,11,245,135,39,59,180,176,75,217,28,108,132,182,18,81,115,44,153,2,66,237,195,82,60,66,212,113,102,102,2,60,195,167,141,210,16,200,212,3,216,68,138,222,7,171,190,163,191,23,20,192,183,109,11,122,40,255,240,238,200,24,65,55,62,2,230,106,84,88,248,6,160,48,143,176,2,201,193,218,168,166,114,48,253,91,83,92,151,231,8,245,254,6,246,27,22,228,244,17,56,171,26,32,103,87,70,58,224,36,159,128,137,151,65,181,212,17,61,233,165,159,197,155,22,99,33,59,73,54,0,229,103,54,20,221,32,229,137,133,164,125,129,54,146,230,190,217,6,144,76,4,165,75,163,254,22,90,97,222,51,68,112,144,114,177,226,39,191,121,53,116,29,205,106,65,209,116,50,11,68,91,179,181,190,113,101,172,163,20,171,34,71,102,196,0,56,196,167,225,69,195,106,54,53,89,34,224,49,40,243,126,189,46,146,178,129,199,173,44,27,199,94,127,233,58,169,235,254,164,59,192,251,84,111,26,69,106,55,70,149,158,156,82,157,251,163,224,205,159,192,148,173,2,218,119,175,22,54,164,127,149,22,54,140,58,57,241,240,10,72,62,191,212,136,244,47,95,159,224,20,224,138,218,113,75,187,118,211,118,37,17,234,52,123,108,12,14,220,142,127,246,98,218,80,218,72,37,68,1,69,72,213,25,9,178,214,85,33,118,93,80,68,40,195,202,69,226,158,52,171,64,39,224,227,232,19,91,192,113,245,153,109,251,175,45,199,22,224,47,254,44,80,196,129,105,171,0,76,255,35,67,90,140,13,173,236,1,240,63,113,199,144,153,185,184,39,193,19,200,143,35,224,187,164,92,188,42,177,50,178,121,241,184,224,31,240,13,89,175,122,14,126,73,26,71,59,147,17,14,138,126,253,14,53,187,229,254,150,115,71,112,167,254,227,117,123,213,181,3,49,115,96,210,155,68,80,246,64,125,25,138,59,152,17,231,164,212,148,164,40,55,249,183,247,219,104,237,248,65,123,241,133,32,118,211,143,64,199,142,0,90,135,57,135,84,108,137,251,214,235,186,99,138,63,118,66,50,149,102,35,2,123,14,73,254,126,9,252,133,79,90,20,166,87,78,222,23,132,241,251,202,168,67,94,20,158,5,86,144,216,23,99,238,29,208,56,120,198,74,55,201,104,1,172,245,3,90,78,83,26,146,240,148,213,134,13,236,224,119,202,229,187,49,156,147,46,179,30,190,176,52,56,28,230,8,43,55,125,40,40,176,102,205,70,142,164,187,171,76,35,56,80,120,125,49,16,30,112,68,104,22,57,129,210,60,232,47,169,179,58,128,197,132,67,227,48,132,42,187,219,244,8,170,162,184,183,152,7,196,109,128,159,95,212,15,221,24,144,44,187,216,171,14,181,179,160,229,69,112,99,80,232,24,98,179,85,7,208,249,68,213,179,53,120,13,146,96,216,82,97,4,174,145,61,85,44,64,105,65,198,240,222,10,63,56,140,30,78,166,141,250,233,108,80,5,198,35,56,117,121,38,237,225,150,139,75,26,209,211,60,138,174,161,242,93,128,63,210,105,227,72,54,96,128,35,233,62,10,237,129,74,250,62,168,223,255,3,142,131,59,127,222,69,100,144,220,132,138,251,83,166,172,23,126,243,77,235,100,231,130,13,55,227,224,13,7,224,73,13,102,30,192,241,13,21,251,143,218,229,8,84,245,41,170,2,60,134,229,58,82,140,36,127,94,179,107,29,109,59,246,189,5,82,86,61,230,137,64,196,177,165,0,228,224,155,221,98,132,94,23,66,17,158,107,6,103,96,126,208,6,156,140,173,116,185,79,32,21,128,199,123,224,154,58,123,139,165,206,9,206,114,175,233,115,175,185,7,222,131,16,171,252,235,208,46,189,3,28,231,232,16,210,137,64,10,237,201,213,224,181,102,152,156,13,105,70,12,136,180,247,14,234,105,63,85,136,246,167,74,0,212,6,190,216,6,9,161,100,236,50,186,217,14,151,200,216,79,57,245,25,103,94,199,133,241,185,177,187,127,232,117,184,249,227,249,224,221,208,193,108,45,143,248,73,117,207,170,220,51,162,183,38,36,155,65,200,203,61,31,145,125,136,104,250,53,210,182,228,153,28,62,100,163,252,45,206,242,205,7,254,2,1,182,15,10,168,67,58,20,158,191,72,66,178,170,213,87,55,5,4,101,53,145,54,170,185,18,168,80,195,215,156,99,42,51,16,199,35,187,23,188,118,106,227,90,41,24,111,128,136,4,63,207,195,188,79,177,237,102,71,217,62,43,70,40,34,119,113,73,42,34,139,81,149,68,72,249,63,111,108,71,128,153,244,156,27,194,18,212,68,25,144,86,251,48,109,6,20,228,179,18,147,217,97,62,208,193,43,192,139,210,200,180,110,168,252,84,49,144,6,160,146,218,191,44,214,15,138,36,2,179,115,95,237,177,109,118,160,73,203,116,223,179,121,31,32,182,51,90,85,195,185,118,187,77,187,128,34,50,215,12,232,230,1,176,21,62,99,197,184,165,122,194,127,0,114,60,254,205,9,53,28,130,176,126,37,210,47,175,130,137,72,132,169,195,255,84,18,28,155,210,227,65,29,85,194,222,187,166,85,133,74,14,247,111,140,180,200,178,195,74,189,200,178,191,187,188,40,47,109,148,229,48,24,149,202,94,196,140,243,255,95,162,68,224,95,63,209,77,161,92,127,57,80,37,136,195,68,20,7,243,179,98,84,194,67,121,213,185,160,59,237,57,248,14,92,140,138,125,106,151,88,41,40,4,28,67,171,57,144,141,64,150,243,131,166,153,123,113,74,242,160,102,239,249,63,0,135,101,7,138,201,70,62,98,177,3,165,148,242,57,138,202,72,130,144,243,233,178,150,105,138,133,208,142,0,191,12,237,24,129,177,11,40,105,45,61,27,145,221,243,248,97,20,45,76,107,29,169,89,132,241,187,117,0,147,93,211,131,79,230,147,135,228,85,40,41,166,145,10,110,106,148,220,217,224,235,41,123,89,98,2,230,186,39,63,70,151,38,104,91,97,203,207,212,71,132,160,184,110,9,52,42,180,229,205,230,47,185,46,118,253,68,187,95,77,94,92,63,120,243,63,14,253,199,128,5,254,46,77,238,253,58,153,190,140,112,146,98,251,35,14,252,57,183,57,21,59,106,128,97,151,154,229,135,2,172,94,10,169,188,193,251,179,136,238,154,246,218,96,236,38,235,161,155,103,91,27,208,30,46,65,209,146,254,71,87,158,122,63,253,77,169,254,219,254,116,183,168,62,233,103,116,4,15,160,13,216,153,0,248,73,78,187,140,200,203,127,0,43,238,14,52,142,255,163,31,144,141,105,238,142,136,85,154,76,114,154,241,29,42,248,227,54,41,4,38,252,55,139,109,26,183,11,222,83,103,4,198,54,160,245,87,207,34,12,195,23,177,234,144,197,128,222,59,164,32,3,248,21,50,99,86,47,125,126,141,192,255,181,29,227,189,52,38,4,239,175,9,154,88,217,76,228,139,181,183,193,63,216,67,207,61,120,39,227,159,107,218,189,136,115,147,113,82,63,99,98,252,185,40,108,103,45,162,72,82,245,140,193,194,244,121,162,160,96,38,11,172,160,26,138,169,64,29,214,148,18,228,38,31,27,11,77,186,41,208,64,42,19,87,223,116,150,248,36,60,137,174,176,172,216,202,160,51,55,85,190,200,59,242,75,88,182,168,2,237,241,76,88,160,77,144,18,41,193,89,246,5,79,10,42,192,213,225,168,140,167,219,39,205,7,209,255,186,135,31,100,108,116,198,187,142,250,110,101,81,4,20,77,52,192,155,110,175,112,133,13,49,62,55,125,108,19,222,123,238,221,66,63,130,2,101,167,85,35,53,91,217,76,222,36,66,42,18,34,108,92,252,158,27,165,209,210,223,39,253,100,142,55,194,124,26,233,99,253,168,111,41,244,198,182,141,28,76,14,222,65,107,72,230,130,165,205,83,110,74,93,213,146,143,20,84,119,163,8,73,171,176,191,253,88,223,27,193,100,107,208,116,197,81,249,229,166,32,155,133,57,198,144,26,96,174,242,114,155,44,10,157,1,28,87,160,125,162,245,161,194,204,86,63,150,242,183,90,151,76,116,148,232,153,139,202,116,110,0,221,207,38,107,88,10,48,168,130,241,242,199,43,91,114,112,68,245,167,228,240,82,120,236,255,251,11,32,212,101,16,180,194,237,84,204,3,88,43,182,221,177,220,113,67,172,231,164,80,230,22,185,81,247,38,250,31,162,181,1,37,184,188,162,125,7,222,141,137,21,92,173,20,207,242,69,251,87,80,65,165,50,51,225,45,166,141,84,60,52,14,202,65,178,72,134,42,70,162,11,177,133,206,2,34,181,152,219,55,249,49,199,63,27,106,57,225,202,84,14,119,44,86,102,173,251,184,72,166,85,208,83,129,19,160,35,162,244,143,83,202,9,236,110,192,43,186,178,233,8,14,141,117,4,143,97,33,115,179,7,175,203,41,70,54,35,40,119,201,88,210,85,71,174,210,79,34,144,234,96,182,149,2,71,48,86,36,239,13,24,239,221,109,47,81,216,127,167,35,18,167,131,67,91,214,234,225,154,123,171,51,252,108,162,167,169,60,49,250,214,16,45,86,200,140,180,81,232,125,22,154,42,222,57,206,75,204,136,30,25,210,56,64,202,222,120,227,145,73,247,64,206,202,110,230,62,89,45,217,113,227,87,210,126,172,182,10,195,68,18,98,90,17,65,254,251,99,55,57,96,171,152,14,46,150,125,34,100,64,221,138,169,61,37,221,91,94,47,243,130,86,239,70,110,154,35,64,214,127,162,63,239,128,218,192,153,43,5,170,220,79,224,143,125,228,64,191,92,230,153,197,226,30,136,7,36,136,179,144,136,226,1,196,171,0,162,236,179,170,65,84,187,148,205,183,231,157,86,16,49,84,114,67,24,127,236,174,160,59,162,114,239,90,116,60,30,251,242,0,157,223,135,121,4,240,40,7,10,132,1,238,184,135,2,158,244,224,56,36,233,241,205,63,0,47,0,255,140,76,232,76,106,169,205,255,38,146,140,43,215,149,212,125,90,190,42,16,75,226,195,221,207,187,36,190,109,211,104,42,101,156,64,191,22,198,23,119,104,49,248,193,111,236,203,177,243,221,44,195,143,51,179,82,95,124,55,179,72,132,11,39,243,100,106,30,164,188,78,1,118,20,250,77,22,175,15,221,249,96,253,175,121,203,219,47,106,26,241,124,107,120,168,174,89,246,11,36,226,111,248,200,23,221,245,142,64,35,222,27,65,163,74,48,114,96,65,7,53,101,44,123,2,83,248,43,255,106,167,254,100,31,52,110,113,159,14,210,129,205,2,127,104,80,113,39,32,201,255,141,8,85,15,192,183,221,2,149,116,193,63,137,4,124,152,90,195,40,81,232,214,200,27,117,215,84,33,119,68,104,71,204,127,144,78,165,187,174,51,44,55,215,165,31,42,52,119,160,202,140,64,209,130,85,69,0,48,7,182,97,61,141,82,188,8,213,168,59,162,26,217,180,189,237,29,43,175,44,17,52,166,222,213,84,144,107,131,105,138,70,135,238,45,85,164,116,111,110,239,185,76,13,74,127,30,85,9,27,97,25,119,218,201,121,233,102,3,50,209,140,41,23,115,160,55,183,159,217,136,208,14,171,138,122,109,16,183,11,251,134,230,245,125,69,102,79,183,107,159,70,86,241,166,137,235,62,231,20,67,244,33,110,63,78,210,18,23,186,109,164,112,161,132,98,160,140,120,101,21,117,232,204,12,14,160,171,42,102,7,56,80,104,88,214,9,178,112,254,83,208,9,214,219,111,199,154,250,159,166,118,65,39,155,21,224,216,154,22,228,235,68,180,192,84,244,173,105,75,186,107,218,125,210,228,254,2,52,12,45,5,96,218,249,144,149,47,157,195,171,184,24,80,75,72,109,71,129,231,193,81,54,97,157,77,200,203,35,112,250,38,144,252,89,123,86,1,201,112,47,40,198,90,130,41,198,163,0,167,60,191,228,69,38,237,127,141,71,47,107,152,33,181,27,190,230,246,169,231,82,149,77,44,70,78,132,33,69,5,14,174,115,34,111,116,2,222,182,129,31,96,154,98,126,164,248,188,124,111,63,160,189,191,56,243,4,66,201,252,163,11,94,11,53,188,237,145,12,247,156,54,89,199,111,127,6,146,42,27,218,80,30,64,67,75,244,43,46,32,214,242,152,192,105,50,156,100,141,173,125,147,145,32,170,94,68,179,38,212,231,113,53,107,3,179,52,219,3,101,127,69,83,215,21,70,213,104,165,159,179,153,46,236,43,35,2,55,28,42,145,158,57,128,45,254,245,11,38,190,245,137,185,10,240,178,253,44,74,55,31,57,101,232,145,4,113,4,236,158,59,22,252,247,186,82,222,79,175,212,130,75,80,37,161,173,249,121,252,50,243,128,120,17,176,28,168,127,245,193,249,12,28,184,41,230,181,49,200,152,40,136,215,215,180,240,34,234,186,42,232,88,12,133,70,66,29,153,218,136,191,100,13,136,190,178,23,88,2,47,238,44,110,252,229,238,32,91,5,237,88,96,182,235,102,232,37,1,87,234,31,103,38,229,96,228,255,245,161,183,110,124,223,236,2,68,70,160,154,223,36,32,58,74,196,4,18,46,217,90,110,166,87,42,198,228,82,99,13,225,163,17,141,39,99,62,178,172,151,127,65,56,100,73,192,163,233,66,103,224,32,182,37,204,240,74,203,99,232,219,190,50,10,119,100,253,42,197,4,42,132,23,93,59,51,149,128,166,238,182,234,62,8,130,146,237,23,88,178,178,87,41,1,239,59,155,90,42,192,37,8,114,156,143,234,88,10,251,59,130,145,146,124,252,59,130,59,164,42,21,188,8,69,56,3,50,233,243,147,197,199,128,53,40,9,201,9,197,62,104,28,188,120,111,209,95,218,89,216,8,48,141,176,168,43,14,93,211,214,87,15,36,138,161,56,171,185,110,59,83,175,69,209,163,49,253,102,184,24,11,222,216,89,35,9,184,38,202,144,9,40,139,251,123,224,237,158,146,233,19,203,23,230,68,255,239,222,112,6,56,232,51,81,91,76,155,158,8,170,158,194,51,80,231,107,187,103,188,144,184,241,244,193,84,110,183,255,237,65,167,82,66,110,135,139,201,125,50,106,41,60,151,213,109,241,103,85,176,31,13,127,207,220,15,45,154,235,242,138,127,127,45,249,151,164,229,249,199,234,209,21,84,124,157,171,21,158,183,116,84,136,147,144,231,61,102,8,10,113,76,164,87,126,240,195,5,241,197,193,13,251,58,88,219,20,80,6,210,168,204,151,38,23,27,116,112,130,156,11,145,79,115,139,173,174,155,228,202,253,156,40,14,128,175,0,176,126,43,198,124,79,218,202,217,81,100,134,3,182,8,122,138,205,133,223,51,26,80,58,227,159,119,172,154,155,155,240,242,234,58,205,67,102,81,186,137,72,228,197,106,231,69,90,18,136,106,166,235,151,175,227,223,159,238,45,64,178,244,173,126,49,34,5,83,27,80,64,118,183,157,108,114,169,133,120,238,90,176,240,201,186,174,214,133,59,175,214,153,205,131,181,1,59,51,96,58,91,122,97,234,135,180,70,199,154,85,185,153,89,158,132,247,60,68,4,48,202,163,241,100,95,158,90,116,36,14,118,190,52,248,235,55,132,18,205,150,125,136,125,22,194,2,103,105,4,74,19,151,8,144,130,178,138,1,174,231,244,192,147,253,133,233,35,140,155,229,189,168,215,106,0,67,187,203,174,18,213,183,79,242,224,116,96,109,30,188,9,134,215,194,247,74,72,127,230,181,31,117,101,56,175,212,228,120,121,49,130,205,187,239,52,253,247,92,7,16,176,139,60,124,87,85,131,188,144,167,227,139,63,146,151,233,117,227,173,26,127,64,100,85,22,144,62,147,22,191,20,255,136,82,55,193,138,200,189,182,13,186,87,187,142,9,81,146,140,165,243,187,70,12,172,15,101,115,117,66,219,64,179,47,51,90,38,149,34,230,69,47,99,168,26,163,246,163,138,178,148,135,18,9,25,231,55,91,44,34,55,86,113,158,247,90,177,236,59,130,49,182,88,156,239,113,176,211,107,88,195,190,241,60,151,105,250,69,78,149,204,72,37,155,3,233,251,94,187,156,239,47,36,184,214,247,232,179,225,34,122,54,213,147,147,79,178,176,160,183,160,183,176,96,238,51,53,206,253,32,214,201,102,99,87,229,199,116,66,235,23,128,134,109,139,142,66,7,126,33,210,98,201,142,52,5,123,211,37,143,48,198,56,104,67,81,195,91,42,91,233,107,131,133,227,40,147,107,137,43,22,244,194,104,45,52,254,43,150,208,247,241,47,122,161,236,190,86,168,161,185,49,249,44,25,48,6,18,157,41,213,63,117,109,176,34,21,217,190,227,93,8,9,69,225,160,230,132,52,178,153,82,49,0,98,132,232,40,203,27,242,95,79,245,89,22,227,102,201,160,12,169,168,123,87,34,156,136,58,86,48,46,44,144,117,98,83,242,188,37,173,123,231,27,95,0,89,159,105,150,213,254,167,15,118,206,81,164,44,23,27,129,151,239,68,3,238,232,218,103,228,8,171,148,29,154,242,22,43,112,11,150,195,204,93,174,161,240,87,228,163,124,19,131,124,243,82,73,136,30,169,221,60,192,60,110,17,161,176,116,26,76,43,212,202,24,69,115,66,122,229,42,132,10,134,110,71,95,212,107,34,245,200,131,127,69,224,187,108,188,208,193,64,69,195,234,161,201,143,73,154,155,43,178,128,57,133,102,93,251,102,128,154,240,231,56,129,54,191,111,125,109,37,40,126,162,149,117,64,11,76,143,113,30,6,172,186,66,206,205,131,174,21,107,131,138,176,105,41,158,89,183,108,180,87,163,188,234,3,193,145,79,225,8,234,61,77,206,163,150,26,230,189,203,131,58,16,234,17,2,116,66,144,231,174,4,135,239,41,185,59,99,79,42,121,171,179,27,80,248,167,160,248,76,228,91,192,220,127,159,250,241,233,180,94,237,60,197,228,115,138,162,217,82,178,152,71,112,54,48,149,7,72,244,139,3,17,48,150,189,164,80,86,112,207,253,131,228,197,80,22,170,168,10,18,73,107,252,47,129,94,88,181,113,221,66,231,160,16,188,5,14,5,218,211,129,102,134,189,72,8,96,166,237,58,128,77,235,102,51,28,255,190,200,170,16,18,158,132,234,3,80,112,151,135,179,229,111,184,101,209,42,108,138,239,67,210,55,88,231,215,215,207,153,3,142,216,218,199,121,249,186,3,47,58,203,57,45,9,167,240,200,120,72,177,54,168,113,222,186,172,137,233,117,92,118,30,230,95,252,76,251,192,171,185,43,167,134,243,14,203,126,234,251,254,203,174,35,118,209,128,121,199,199,65,74,77,162,0,63,44,180,22,92,140,37,83,207,132,85,247,17,166,214,166,9,65,200,90,109,247,69,215,121,165,216,60,5,43,25,43,25,235,204,52,153,31,108,63,107,125,190,82,167,149,26,151,217,175,80,242,233,168,4,222,169,88,244,132,134,126,152,40,126,64,231,139,184,30,57,37,233,129,131,225,171,131,90,207,44,41,255,183,75,75,16,235,170,105,211,46,203,44,61,209,212,123,65,207,165,182,117,177,234,113,46,89,80,166,208,142,172,3,245,116,186,46,178,250,185,228,73,236,142,153,225,75,139,246,196,9,1,182,47,14,86,131,213,100,118,99,207,91,17,143,234,218,54,99,39,6,166,238,131,244,54,255,46,110,101,99,218,64,161,140,142,156,34,39,116,12,36,14,186,20,201,219,177,204,160,91,196,113,251,112,196,55,76,172,55,100,42,87,66,183,82,8,34,50,71,46,172,160,30,134,191,187,145,107,227,79,114,203,232,24,255,201,46,84,166,16,108,247,44,118,134,132,5,227,91,86,211,79,90,144,21,224,222,65,74,134,71,134,71,86,193,128,49,188,137,193,84,201,96,203,102,195,192,106,41,33,38,183,185,28,204,80,69,172,151,78,135,209,135,26,56,210,127,150,107,18,16,174,21,132,213,68,75,90,23,175,69,244,133,128,236,72,25,239,142,34,251,149,230,147,59,157,220,130,48,43,153,34,203,226,40,185,57,46,222,219,103,24,239,36,202,205,233,151,247,110,228,221,255,207,57,242,63,103,166,28,217,213,151,251,67,93,186,248,167,25,178,113,88,69,187,232,24,193,17,50,197,159,219,61,99,158,12,205,161,82,50,133,57,100,120,107,181,57,51,103,103,77,214,72,249,120,114,187,69,197,255,162,93,118,36,51,102,97,157,9,192,227,12,75,209,213,179,183,158,11,80,137,160,31,199,67,191,77,60,162,167,144,146,155,16,147,198,108,213,80,165,213,195,33,148,228,198,61,161,139,14,193,198,195,194,211,253,15,86,239,43,165,249,61,46,86,186,32,174,118,3,72,134,229,132,136,140,206,146,140,76,142,93,234,207,82,40,81,3,73,212,133,215,43,44,177,77,201,159,104,161,230,57,229,107,93,49,127,25,34,194,194,36,213,203,208,66,79,200,240,126,105,121,67,35,218,145,132,161,10,60,223,152,56,159,218,95,23,61,200,98,162,167,49,237,85,28,88,242,176,188,45,97,150,160,103,37,99,221,146,103,157,1,177,208,111,247,81,145,29,189,214,205,44,22,40,34,255,143,152,9,55,212,176,47,137,54,99,140,190,121,55,128,156,94,74,139,109,134,171,109,188,48,151,161,162,100,213,16,146,174,111,213,49,28,96,182,163,27,16,158,172,193,211,157,73,151,249,191,60,49,208,117,130,30,212,246,139,254,162,133,210,147,189,90,249,178,68,191,252,251,20,45,180,76,238,43,221,110,168,146,8,245,207,162,6,180,80,180,80,146,255,208,152,222,104,133,215,229,236,235,39,18,117,109,227,49,145,144,29,177,226,65,79,223,3,125,225,93,100,223,37,190,178,145,69,10,245,226,94,29,137,44,10,207,129,210,205,118,94,244,202,226,53,52,119,175,161,173,252,123,21,177,134,142,129,201,130,113,189,22,99,243,10,107,192,113,43,201,151,251,33,185,121,11,131,248,114,48,229,116,77,132,175,79,150,134,107,216,175,48,46,79,50,177,104,255,63,150,4,121,214,25,200,176,21,77,159,35,41,214,206,130,170,225,82,59,238,74,81,38,90,104,40,1,122,17,39,98,218,39,62,25,3,75,21,43,180,65,168,91,33,124,118,90,227,152,234,105,158,28,135,77,106,77,142,128,12,143,108,52,26,109,176,172,250,208,114,168,208,107,58,90,219,111,5,66,150,92,104,134,92,253,170,5,47,12,255,74,96,85,152,135,240,254,38,35,114,132,243,194,75,76,134,85,166,144,139,236,234,216,66,141,23,47,18,7,111,146,13,75,157,158,40,200,159,4,157,78,154,144,12,143,140,12,15,143,235,181,53,197,22,57,171,22,59,30,86,11,255,172,229,157,167,142,132,226,159,23,189,178,60,34,216,145,66,104,79,207,10,228,239,185,162,101,168,58,52,199,148,29,175,68,4,95,127,196,233,70,109,41,134,133,92,248,135,133,35,215,18,181,130,191,202,252,159,250,45,163,100,248,9,112,66,221,94,237,202,28,5,254,255,75,50,17,50,91,159,49,221,117,15,123,52,199,92,144,226,130,197,2,22,153,27,172,63,3,92,114,204,242,172,173,156,39,42,34,85,49,176,254,147,4,22,134,124,212,93,67,142,101,203,89,50,57,131,204,20,81,42,12,141,126,114,38,227,191,112,162,88,201,142,44,228,183,8,114,86,49,67,13,169,136,18,243,207,67,125,42,184,100,44,183,100,101,188,195,142,112,228,197,110,66,69,59,152,214,56,174,222,40,180,158,108,161,127,214,155,83,60,122,209,45,102,30,18,78,102,194,18,198,222,168,199,67,63,78,252,191,74,58,98,98,141,255,33,88,69,11,211,82,52,97,43,52,23,103,98,141,104,165,230,41,106,250,207,69,22,61,84,6,192,25,122,229,107,207,29,56,56,176,117,180,156,243,155,214,152,137,117,102,147,236,21,138,230,62,98,226,242,242,33,226,9,19,235,235,215,29,59,45,99,92,219,209,80,153,101,141,103,165,162,120,67,24,28,14,63,177,34,173,73,66,188,207,74,186,47,186,38,204,130,174,135,46,192,0,220,98,228,161,40,136,152,197,212,115,111,63,203,194,135,214,204,43,37,240,106,0,119,66,148,170,72,17,31,75,26,113,37,223,121,25,52,37,21,182,81,93,223,119,130,130,111,2,207,131,9,69,247,35,191,158,171,243,117,147,233,155,227,69,101,222,99,99,128,0,216,180,222,48,108,43,156,148,254,229,193,186,239,166,183,107,31,204,126,219,183,30,130,234,202,68,246,99,146,82,29,224,11,226,136,98,97,32,171,193,8,87,8,210,199,119,136,218,96,30,144,141,243,96,183,233,185,25,231,211,179,139,71,111,244,57,177,26,183,50,219,164,99,239,189,30,102,232,58,192,247,130,188,238,48,186,200,50,15,120,191,253,88,14,66,142,49,19,67,249,222,238,167,170,189,116,159,233,8,77,47,100,170,186,198,195,8,49,137,90,128,126,48,4,218,176,215,138,82,69,228,209,54,220,142,75,179,186,32,136,125,193,218,202,78,229,119,12,12,68,38,58,138,22,106,2,16,89,149,64,186,182,204,37,250,163,253,44,139,13,129,198,65,10,151,203,222,199,186,12,97,255,164,226,7,27,22,120,118,72,59,252,162,155,123,122,213,253,54,239,50,104,100,106,229,139,232,227,31,201,203,150,146,46,217,143,202,167,92,37,12,174,61,218,215,216,166,115,144,99,181,142,12,125,227,177,47,237,235,62,23,217,54,137,238,0,226,16,180,138,115,26,205,28,48,58,181,18,156,9,159,77,10,153,111,147,136,227,237,186,232,58,253,232,150,227,114,149,114,122,119,60,55,119,89,38,120,220,182,230,49,81,92,140,179,230,169,163,238,93,53,55,89,219,190,113,162,111,17,236,45,106,63,73,39,234,127,99,43,250,105,158,135,105,90,231,131,248,208,84,108,147,111,63,177,219,123,201,136,45,225,14,245,61,46,166,24,105,145,9,219,244,33,90,11,41,69,229,4,128,179,167,34,250,0,117,230,0,58,181,73,152,130,49,62,125,141,191,189,4,3,221,117,24,22,129,231,194,190,51,178,184,157,216,52,134,253,9,12,162,127,166,132,166,165,92,46,58,15,60,86,93,186,107,39,120,27,80,79,75,144,174,245,159,103,19,245,29,61,117,77,242,101,3,184,161,62,127,33,151,96,0,46,33,154,66,234,204,181,200,51,105,196,24,48,158,154,40,121,225,247,8,155,14,174,219,252,238,185,250,165,189,83,88,97,152,78,210,167,38,247,141,157,170,222,179,240,86,74,79,136,206,210,7,123,172,48,209,44,35,241,143,164,111,164,96,123,105,223,38,112,89,130,220,166,206,162,25,61,98,14,130,207,26,71,62,29,8,140,95,205,235,104,118,26,53,219,119,78,8,178,100,123,129,135,168,13,188,78,235,33,33,138,143,179,174,182,48,144,199,128,75,179,143,39,119,190,95,177,13,106,62,237,97,197,89,112,54,229,44,77,140,78,244,77,72,252,107,175,211,89,101,150,218,242,170,191,123,86,125,235,30,19,2,46,183,83,162,190,16,0,121,169,54,87,215,39,130,181,66,126,143,7,85,210,121,50,182,239,238,131,192,47,186,153,36,194,166,193,168,91,111,61,216,162,137,107,103,105,166,241,248,84,246,235,146,205,31,21,41,14,219,146,98,124,145,186,76,24,181,230,190,223,251,124,241,103,33,203,79,14,11,122,6,222,146,103,13,225,127,229,25,113,229,62,17,97,212,52,102,39,45,89,128,131,109,88,22,115,77,230,155,183,20,139,73,171,31,187,69,14,24,22,135,187,14,42,120,117,215,222,133,160,121,222,33,45,97,71,215,35,44,190,0,108,26,188,54,7,134,231,254,55,1,232,85,106,85,95,250,197,35,110,178,32,243,159,89,96,163,202,159,236,92,79,224,11,250,38,26,207,86,99,200,57,190,27,95,88,10,214,44,16,242,75,165,21,4,157,188,39,183,47,235,230,202,50,253,107,165,27,116,61,68,187,158,231,187,113,28,2,253,205,210,165,99,215,24,112,241,216,119,232,179,225,127,248,64,164,72,248,197,242,46,129,233,243,239,104,210,250,229,172,20,14,229,19,57,243,140,87,126,47,199,58,197,235,99,220,227,253,197,189,55,252,215,173,227,4,94,62,36,51,39,178,102,225,83,62,159,231,247,44,180,213,202,246,170,248,132,178,94,30,18,115,110,55,146,240,193,219,61,173,109,207,135,223,22,0,103,33,200,83,139,110,121,210,119,243,200,109,82,112,133,225,15,27,78,122,145,207,134,77,71,140,60,187,255,156,144,51,216,37,111,187,22,126,249,151,15,148,206,173,72,250,255,181,221,23,10,233,206,9,231,87,55,48,178,163,62,156,32,139,239,4,86,129,178,124,184,146,99,72,237,13,17,208,177,168,58,234,114,90,215,93,23,80,94,68,101,111,53,66,189,187,120,15,234,218,88,119,31,97,74,100,82,190,203,194,2,254,121,205,105,172,55,77,240,155,84,31,93,133,36,203,245,95,213,51,221,145,42,179,166,87,211,9,59,151,58,20,4,235,223,134,221,218,189,215,190,43,186,130,250,200,84,53,141,156,121,40,143,145,150,127,127,109,35,46,234,121,160,190,126,239,242,102,248,18,12,224,46,247,206,59,163,89,158,99,229,157,16,230,85,127,86,132,231,211,189,171,209,160,94,93,42,19,175,61,238,125,220,208,49,13,65,193,14,157,105,174,127,17,10,30,173,84,10,18,232,149,192,39,248,155,213,167,158,36,94,255,166,212,148,218,126,254,225,135,225,172,215,162,118,205,208,162,169,167,70,240,200,203,72,72,108,221,174,1,228,73,207,90,87,65,4,116,222,50,167,235,100,174,253,85,170,227,164,170,122,45,1,212,55,203,116,223,90,194,72,160,71,241,135,126,166,54,96,248,242,191,86,29,32,151,32,168,210,77,159,191,32,135,31,238,81,117,179,175,11,145,168,208,205,165,214,178,243,24,212,61,25,121,201,11,166,89,123,39,206,183,136,75,0,26,93,199,4,185,175,117,237,132,29,228,214,127,154,155,173,181,84,25,22,119,60,154,41,210,187,109,59,225,250,144,210,223,169,3,251,80,189,149,106,224,194,41,193,138,174,63,225,133,54,35,255,247,121,238,231,98,3,199,93,16,86,129,11,237,111,104,235,146,249,233,7,154,221,245,33,118,3,162,231,35,54,216,10,149,64,74,115,41,103,143,93,142,147,30,140,88,238,77,37,154,117,185,63,90,11,131,96,17,136,223,1,197,23,177,221,115,251,199,115,132,57,240,243,212,243,31,129,23,157,24,6,165,38,194,183,34,146,152,74,213,201,223,49,209,241,136,118,43,30,112,122,157,62,116,70,150,198,144,181,157,214,117,119,113,36,138,177,143,221,160,224,151,221,151,177,108,120,130,85,130,65,219,132,188,110,237,206,179,127,121,49,224,247,245,96,51,90,186,123,30,113,105,216,152,166,4,10,17,129,225,26,78,44,226,182,250,5,210,43,121,59,41,132,52,8,63,201,191,158,21,155,222,114,196,229,74,127,185,117,123,149,242,123,93,240,18,89,250,27,115,132,34,14,94,154,101,110,252,123,178,112,18,6,29,1,213,213,27,86,236,172,3,231,174,224,85,38,191,173,208,204,119,166,112,116,140,131,88,27,243,8,228,76,132,150,29,37,171,27,146,56,131,217,132,78,51,196,255,178,55,113,61,240,108,197,89,63,236,160,32,228,233,152,158,190,169,222,238,251,164,49,41,88,226,240,135,231,26,7,69,149,229,8,147,239,124,3,54,170,152,225,183,208,70,14,46,139,71,67,247,33,237,163,99,51,141,153,151,246,253,211,185,51,195,239,71,76,90,140,243,50,112,131,239,111,88,64,225,138,202,70,192,248,169,51,115,98,152,139,175,220,176,229,33,222,45,211,97,79,77,124,168,1,52,195,192,140,237,205,61,243,216,159,216,208,38,159,147,87,238,175,104,133,233,64,26,222,62,101,245,35,121,68,56,93,5,202,180,126,109,91,114,132,93,129,23,177,176,2,98,156,97,97,185,40,240,121,69,125,103,193,166,127,150,82,181,140,63,170,82,51,120,188,233,40,35,8,151,217,171,208,228,99,177,80,208,185,179,133,90,175,243,153,114,30,230,186,97,145,192,244,187,122,49,174,166,102,55,131,235,175,192,133,47,228,148,68,242,172,33,115,233,25,47,79,20,218,236,115,183,167,206,163,98,194,5,45,216,144,96,72,163,88,115,79,231,89,211,132,238,64,244,70,41,228,175,204,182,100,109,84,193,95,193,89,255,228,147,20,228,97,203,59,58,114,215,142,237,168,249,67,186,106,35,8,163,255,94,202,69,115,1,178,6,190,203,2,28,209,24,217,166,232,230,95,113,176,96,248,7,113,131,14,25,165,135,18,103,67,200,155,139,134,73,156,120,124,65,182,137,220,6,206,220,250,32,175,234,99,61,165,226,123,99,159,206,253,181,53,207,233,218,111,48,227,162,120,45,199,141,160,219,169,157,202,134,168,182,210,253,180,162,227,119,36,216,244,88,116,146,195,16,144,19,49,225,10,38,137,88,127,240,62,159,133,251,43,174,120,249,115,149,4,94,54,122,39,202,124,155,174,234,242,148,164,158,158,231,68,68,15,157,118,111,123,230,124,2,164,111,70,57,46,188,151,3,122,151,203,114,75,169,132,137,174,195,8,95,86,176,81,40,171,65,59,54,81,15,237,99,21,160,219,73,33,146,221,138,132,224,27,246,181,22,38,140,49,186,59,110,171,207,129,245,184,154,145,116,79,234,199,235,53,230,205,112,97,237,155,251,206,25,67,127,93,82,164,67,57,155,227,183,180,72,87,162,98,124,177,71,50,165,139,229,229,105,9,159,163,40,42,86,45,82,172,21,13,224,228,121,179,152,192,144,78,73,190,75,11,87,210,248,204,151,202,23,102,248,219,229,217,115,17,158,55,9,178,123,114,195,150,23,73,140,175,255,34,15,68,33,239,193,255,142,33,182,136,129,172,0,71,155,156,238,239,87,5,18,201,144,57,248,74,190,251,232,99,161,190,113,38,166,141,207,108,147,243,209,159,130,245,227,151,84,73,126,82,251,143,203,14,5,223,110,31,255,128,128,160,199,233,44,224,184,239,105,161,190,12,90,157,16,107,230,252,248,186,156,188,21,196,171,72,66,53,24,247,254,223,250,229,143,128,42,165,180,23,138,37,79,255,98,82,27,83,162,2,228,161,194,119,34,32,232,0,105,85,200,227,154,231,116,103,55,215,224,90,144,206,161,154,79,132,46,146,181,231,204,0,79,166,186,127,34,243,84,210,35,153,69,158,195,57,6,249,184,185,217,139,92,92,189,248,238,92,119,108,96,232,245,113,95,194,69,252,213,23,99,22,137,175,222,68,206,198,14,38,250,90,124,202,21,118,9,46,129,3,17,82,50,41,50,21,47,123,52,196,13,176,93,231,138,35,126,49,111,59,249,138,135,239,183,67,144,26,117,24,105,201,36,131,122,61,0,10,126,95,67,100,13,165,216,244,69,64,175,59,135,40,40,127,208,181,250,157,241,247,92,253,10,144,38,55,24,255,239,130,177,89,53,211,168,213,44,68,4,177,129,242,239,99,181,214,117,120,205,31,120,84,160,54,141,131,191,28,75,18,68,60,110,167,65,96,151,222,109,54,178,152,74,13,100,216,249,15,249,218,149,120,196,93,57,232,60,17,132,242,35,174,206,168,69,231,224,36,52,161,58,31,124,239,64,248,230,117,201,45,69,199,216,64,165,159,88,131,188,67,81,36,141,71,1,116,144,155,183,77,159,118,214,48,253,102,139,49,214,112,238,7,220,26,255,135,92,127,49,211,143,75,121,186,252,139,11,151,192,90,171,13,178,95,253,72,160,231,177,47,234,116,155,171,129,139,95,246,29,219,222,168,43,65,14,27,143,204,155,88,33,86,40,7,145,209,172,143,187,245,224,166,239,102,48,201,229,75,57,70,52,194,252,89,150,113,165,28,25,67,242,157,161,155,252,16,93,66,69,101,72,40,62,210,254,101,26,120,165,197,41,39,83,24,40,127,176,144,153,145,82,116,190,93,205,54,96,223,150,201,214,143,192,156,84,243,243,62,111,223,12,121,98,254,62,84,148,59,35,76,241,234,249,36,165,152,188,216,135,43,162,32,118,154,183,221,12,253,154,191,248,229,118,241,48,101,160,138,106,241,2,135,54,161,37,17,184,104,202,116,213,179,37,202,38,153,243,11,7,212,209,108,97,106,17,28,134,86,145,212,31,253,251,83,54,145,23,190,198,139,243,149,58,76,155,100,137,39,231,237,155,62,185,95,218,140,228,178,96,49,125,50,183,151,25,76,116,51,107,173,75,230,38,78,190,85,253,36,80,171,219,164,101,135,71,166,153,179,153,193,0,214,194,112,227,205,14,138,19,236,149,177,31,17,164,91,222,164,189,17,184,70,236,88,152,69,53,168,59,229,34,24,123,253,43,81,34,7,188,237,61,6,39,60,193,223,136,66,41,71,161,32,126,201,77,30,81,143,198,71,191,119,82,203,62,69,7,83,238,62,140,59,63,250,173,167,41,152,167,103,66,142,68,61,168,99,175,196,35,250,27,125,60,75,93,80,133,189,51,20,171,99,142,251,201,184,254,196,125,253,129,187,28,210,144,150,158,237,21,35,178,87,82,142,220,200,106,220,37,108,217,140,122,99,120,80,5,189,116,19,229,87,111,116,104,199,205,56,223,210,94,240,164,226,129,208,184,85,223,11,85,82,16,162,225,47,198,158,164,173,230,141,167,190,129,185,73,13,209,198,192,146,83,218,181,77,188,40,138,49,52,137,189,90,160,251,172,233,83,79,222,187,192,182,93,41,174,131,51,230,192,51,43,69,61,211,156,250,152,232,5,219,248,224,199,117,81,61,218,47,108,10,44,221,211,161,228,108,185,41,180,142,220,144,90,65,211,47,168,230,102,78,190,83,89,207,35,202,134,93,198,176,26,70,211,217,127,246,210,71,228,107,181,181,83,252,93,121,118,194,127,67,110,236,151,248,174,184,246,212,175,200,232,191,248,41,141,90,185,225,111,236,114,31,73,123,49,215,187,150,192,81,112,209,205,32,157,125,169,241,28,181,63,5,38,154,139,124,163,79,243,161,82,35,190,91,24,177,173,116,30,60,55,142,230,97,35,3,132,183,27,115,89,252,155,21,34,154,183,227,211,96,156,214,42,245,251,254,156,117,202,209,53,3,115,255,82,137,231,249,222,139,70,198,100,206,99,105,154,226,203,222,190,190,146,139,229,33,197,166,7,22,239,246,111,153,106,111,111,159,118,149,223,77,202,239,150,198,179,92,9,170,222,143,146,43,25,196,40,245,211,255,43,231,99,65,30,41,175,123,236,96,153,182,132,236,153,12,103,63,238,133,211,48,134,64,183,233,7,194,95,101,36,252,16,53,155,143,70,133,228,231,105,34,215,243,149,78,44,28,242,188,109,73,4,121,17,71,164,170,225,207,118,123,6,253,173,102,162,204,124,150,21,229,83,224,254,253,138,185,209,51,33,126,244,183,51,135,26,123,184,154,3,184,7,111,254,236,140,182,31,157,136,193,151,23,243,103,168,119,5,164,228,55,119,78,41,43,112,243,152,36,100,160,150,34,161,211,91,32,169,204,167,23,225,15,182,190,87,242,37,133,2,101,240,175,164,175,29,102,28,100,114,29,109,202,79,159,168,4,77,58,153,20,240,181,125,176,2,192,148,31,158,38,155,255,204,147,205,247,106,238,74,186,69,185,227,28,92,229,124,122,3,18,11,221,192,240,15,191,94,243,219,77,208,17,219,206,154,18,251,101,51,35,207,170,249,53,218,40,231,183,35,133,243,171,18,7,16,234,58,73,175,47,60,95,86,40,110,120,99,81,170,140,180,185,235,11,73,161,160,172,168,195,83,234,25,99,3,162,140,16,29,231,115,161,161,115,109,235,219,21,194,75,236,183,2,239,135,133,140,117,131,110,87,248,137,5,188,41,148,148,196,134,85,210,11,75,93,28,192,162,31,104,168,82,248,63,178,203,122,184,213,241,246,68,176,41,236,184,211,143,97,240,166,190,175,185,202,24,82,172,34,108,234,21,163,127,237,17,145,137,141,120,161,51,88,164,66,36,149,194,31,244,209,31,198,166,206,71,225,202,116,237,171,197,251,47,109,83,209,228,75,171,30,103,188,2,24,124,172,102,161,218,71,153,36,198,24,196,145,243,99,76,200,69,65,251,217,24,86,2,228,178,50,235,233,184,32,98,93,117,159,24,100,141,135,151,162,177,133,220,23,4,119,150,90,146,203,126,60,125,58,16,133,228,152,36,241,44,220,245,242,164,164,61,54,29,197,64,167,252,226,20,4,46,109,24,183,219,253,198,56,97,103,207,7,208,93,17,3,16,237,18,37,101,10,194,229,38,69,16,242,88,179,181,206,38,81,252,185,255,48,241,125,168,111,80,243,253,162,201,169,107,254,196,206,243,212,236,170,217,100,54,249,251,188,54,229,27,34,38,9,78,137,147,138,18,118,237,136,52,129,21,207,233,119,247,193,107,250,177,62,139,115,36,43,2,223,176,166,116,166,65,214,172,51,30,131,38,37,236,146,110,63,67,196,247,90,118,242,222,37,99,39,132,8,202,245,72,27,7,158,123,179,147,207,20,27,88,4,11,83,12,63,107,215,30,143,57,44,139,139,208,230,85,63,11,236,54,134,68,147,60,75,13,3,65,236,24,252,254,186,78,108,158,241,217,168,51,140,196,51,175,159,21,155,24,231,243,23,115,104,99,17,78,153,84,132,125,176,227,163,41,109,126,120,253,255,1,60,64,195,191,75,255,232,247,238,187,239,174,217,55,88,127,253,72,148,79,145,24,58,117,28,13,255,228,156,162,164,56,9,129,21,77,154,52,41,30,83,15,255,101,177,16,137,160,149,228,227,134,113,101,94,217,248,115,181,250,179,243,74,22,202,138,111,212,5,62,198,121,99,220,1,191,161,255,178,160,77,218,166,101,246,212,63,122,244,168,232,146,75,46,73,213,221,9,63,174,190,250,234,4,142,162,248,234,132,38,135,54,214,9,1,228,65,112,244,149,87,94,41,252,2,62,32,161,19,162,161,195,60,122,175,56,221,21,137,162,54,146,208,41,138,243,20,32,97,78,147,121,100,243,210,232,191,44,116,181,14,228,166,236,124,211,121,34,237,200,206,55,62,216,98,139,45,180,204,172,140,163,133,101,254,129,255,80,214,201,39,159,156,121,147,255,83,140,187,154,95,140,210,73,6,49,60,39,243,223,218,165,87,163,35,82,190,40,22,146,252,70,107,122,249,91,76,15,160,53,178,168,79,242,133,155,206,132,192,75,47,189,20,227,180,140,191,56,233,180,180,19,200,131,224,26,114,77,173,36,202,10,205,155,149,165,18,124,148,114,124,188,93,118,217,101,42,240,145,185,157,172,19,44,191,92,225,127,121,115,81,148,80,209,246,219,109,151,146,127,152,231,162,216,138,36,196,84,36,70,93,189,207,182,157,54,77,153,50,57,110,143,183,182,97,142,136,242,43,201,46,202,21,205,3,77,249,220,231,62,215,147,223,69,221,221,221,73,158,188,27,100,140,145,178,206,98,61,86,15,157,160,12,214,78,192,71,28,124,180,200,239,127,255,251,73,125,198,255,21,126,6,23,25,127,228,60,75,41,121,16,152,245,208,7,81,40,182,69,30,52,90,7,252,145,101,59,57,217,122,123,251,237,183,175,217,141,79,239,184,163,226,31,242,159,37,248,201,180,105,221,17,235,38,214,214,140,155,207,127,152,43,162,8,179,236,81,30,221,183,151,162,88,139,38,202,250,32,53,246,82,222,250,27,172,175,114,29,229,30,116,208,65,150,61,2,135,89,79,20,165,37,151,90,82,229,213,236,123,155,167,217,122,154,193,55,224,203,162,40,204,86,169,235,255,238,238,105,21,207,179,15,144,195,193,99,81,68,38,175,36,20,163,194,68,118,219,37,207,236,134,241,3,255,69,49,110,143,10,175,98,76,210,114,178,227,199,28,135,150,229,241,95,198,79,156,248,82,101,166,214,195,140,119,207,252,3,158,89,218,5,93,225,61,116,229,243,159,255,124,50,182,212,73,254,106,235,199,179,207,62,91,243,72,120,184,164,126,49,64,71,163,71,143,137,196,193,54,121,214,169,55,18,70,45,129,135,40,174,59,178,27,18,162,88,199,183,154,222,102,185,229,226,181,126,86,38,187,229,150,91,122,215,138,130,11,224,3,244,63,111,30,138,17,39,154,144,172,61,39,246,228,117,145,173,61,197,121,60,129,165,209,31,228,102,214,80,150,138,228,89,248,137,202,217,194,75,179,252,39,43,103,83,150,233,109,168,27,190,52,100,72,90,103,40,134,236,232,250,235,175,183,106,59,238,74,219,141,54,178,238,110,69,66,31,10,189,41,74,18,253,73,219,32,187,2,83,89,98,218,29,203,51,54,206,208,23,49,208,84,200,88,159,222,41,166,119,189,244,169,75,101,36,31,39,40,220,228,9,232,174,63,254,200,86,89,253,82,44,39,117,41,61,51,57,137,242,197,24,164,237,69,247,86,148,100,19,131,230,241,233,89,150,23,89,253,204,129,172,190,132,114,111,186,233,166,104,226,196,88,191,226,247,31,89,18,57,144,113,99,78,54,59,33,43,106,125,210,87,217,176,209,236,226,155,86,158,88,196,202,157,48,8,49,72,193,32,84,125,156,80,92,98,16,34,153,210,2,97,39,47,201,238,33,157,184,76,44,132,77,224,43,158,163,73,86,57,188,78,159,65,204,49,244,200,225,141,42,176,194,180,80,146,172,176,194,138,41,197,2,229,81,6,249,49,218,136,55,107,36,161,147,34,217,10,43,147,111,98,36,22,91,125,15,211,176,180,69,142,65,8,133,164,88,161,181,109,114,254,134,18,40,57,100,50,146,152,152,145,88,178,149,113,22,245,201,202,29,140,87,217,117,160,240,101,12,170,9,22,205,128,13,11,126,12,35,69,6,33,137,105,170,109,145,115,15,146,234,100,11,171,62,67,232,64,49,139,18,79,206,215,137,196,115,77,159,67,136,45,129,3,75,45,185,148,62,7,7,32,234,189,56,32,2,135,8,15,24,24,73,226,229,162,248,232,47,118,49,234,32,220,3,139,109,183,221,46,66,137,71,66,17,6,115,228,57,10,122,8,180,120,61,104,25,102,92,249,198,55,190,161,121,101,231,142,182,83,118,166,137,240,60,58,18,175,7,253,163,237,86,158,102,172,241,143,236,0,209,250,242,12,66,204,187,185,69,240,17,15,133,72,66,236,229,150,36,30,22,250,189,120,175,235,123,12,10,204,191,53,215,92,43,90,68,22,60,192,26,227,153,120,214,68,39,156,112,130,206,145,33,98,220,242,5,71,250,253,153,207,124,70,203,17,79,85,133,29,240,7,118,217,126,231,54,162,9,15,89,228,40,125,24,59,166,9,165,181,183,8,137,69,174,109,151,93,55,145,120,202,20,86,14,94,176,240,52,101,135,120,245,38,120,3,62,145,48,70,34,36,137,215,84,52,99,185,25,42,108,139,167,148,226,33,239,101,183,80,36,187,1,162,133,22,92,40,146,131,33,35,22,183,224,62,101,242,221,164,73,19,35,230,186,37,157,87,130,15,40,35,106,205,43,112,56,166,221,43,168,225,30,37,18,229,83,39,125,99,124,254,239,255,254,79,21,88,44,124,153,31,40,194,89,136,66,123,193,211,122,21,86,214,190,254,190,202,33,194,218,47,250,70,255,67,26,56,16,48,131,80,53,133,34,244,159,177,103,113,192,66,0,90,137,44,115,197,21,87,68,11,204,191,128,10,232,204,45,18,115,20,28,65,25,53,70,20,38,204,39,254,120,102,52,223,228,159,29,119,252,180,62,135,127,136,87,90,36,158,218,90,15,114,144,159,54,223,188,126,131,144,132,157,140,196,187,77,231,185,156,23,84,200,19,172,124,83,12,250,78,54,226,241,169,237,162,205,214,118,238,197,179,84,219,135,92,104,137,121,63,94,104,13,60,238,186,235,174,139,228,64,218,132,214,12,27,58,76,229,54,148,232,33,117,46,4,100,231,72,66,255,90,177,200,245,33,115,226,137,39,106,93,245,26,132,88,184,251,6,33,227,125,134,143,240,38,228,158,94,222,55,41,242,241,49,43,83,138,231,178,206,197,197,151,136,101,74,112,218,79,226,117,172,252,79,118,195,70,178,179,46,34,191,120,207,43,239,100,237,132,130,5,30,235,39,230,19,252,216,111,19,252,24,121,115,152,242,227,73,17,206,88,36,148,196,208,26,214,96,226,137,175,114,56,115,144,126,213,74,190,140,81,207,250,102,139,45,62,169,180,203,248,49,134,63,234,66,254,96,190,219,252,135,230,169,146,70,218,115,251,237,183,107,51,76,14,6,254,181,228,224,90,237,158,211,247,192,143,250,81,144,84,163,223,115,90,126,59,191,51,103,199,186,12,66,61,6,5,240,202,210,134,27,110,168,116,31,153,16,57,140,177,131,175,176,62,18,47,107,197,41,57,116,222,178,247,24,132,186,34,223,17,128,151,40,198,192,191,241,115,141,143,36,60,154,242,179,167,159,126,90,29,121,88,131,203,206,32,197,127,230,141,37,248,98,53,131,144,236,106,175,48,8,41,223,24,63,151,200,168,49,223,128,198,216,60,69,78,156,52,121,82,74,70,181,186,234,189,162,67,88,120,161,133,43,178,51,63,63,90,69,1,234,127,128,177,132,57,136,241,131,196,218,8,216,48,63,178,137,249,198,187,122,198,79,206,124,81,24,250,227,135,97,133,126,51,126,24,149,253,241,147,243,138,42,198,143,250,209,131,128,255,148,231,231,207,91,15,83,87,47,93,113,17,227,199,55,140,3,138,115,28,204,124,131,161,223,191,85,87,89,85,191,181,245,163,189,67,215,51,118,204,88,85,228,218,179,78,188,162,155,50,167,157,188,177,237,132,62,161,39,3,87,81,238,251,206,58,214,118,217,217,163,99,136,46,192,79,198,47,145,87,109,173,136,222,205,248,37,115,222,95,43,202,249,198,209,240,17,195,35,217,13,18,161,83,69,169,111,107,79,227,93,224,5,207,208,71,192,79,100,103,143,58,153,226,52,78,130,119,2,111,159,15,243,124,155,109,182,209,54,202,153,209,209,79,126,242,19,93,55,154,156,45,187,61,244,157,175,163,193,120,7,254,67,239,224,189,114,222,174,202,229,192,66,66,58,70,67,186,134,104,221,198,91,169,163,147,146,25,132,232,99,171,12,66,163,160,135,98,68,41,74,178,91,82,97,12,108,45,129,75,56,237,131,51,89,153,63,214,47,244,210,110,91,95,100,113,130,77,4,83,167,206,167,27,9,40,23,156,181,245,5,250,37,211,171,97,244,91,110,217,88,119,111,122,53,242,27,174,173,182,234,106,50,206,93,74,207,76,78,50,122,102,116,155,252,126,90,29,61,133,224,31,50,24,41,230,69,227,213,153,134,57,0,47,50,125,9,114,207,228,73,147,83,115,64,245,133,66,235,145,233,224,145,224,168,207,35,169,31,90,219,10,89,25,157,156,209,170,96,16,242,71,181,193,123,221,33,36,131,244,177,143,173,219,224,151,131,43,251,200,81,35,35,99,26,40,60,64,236,34,239,17,132,24,152,16,12,68,13,66,50,201,252,29,66,8,163,178,93,52,194,34,155,77,166,136,65,9,77,130,32,168,193,71,202,200,35,126,18,142,64,119,100,32,252,251,76,65,189,220,228,27,91,212,80,150,181,59,207,74,44,161,153,180,79,166,192,33,127,72,49,4,116,135,144,192,146,49,111,143,65,200,69,39,157,116,82,5,248,17,28,150,80,35,79,239,2,148,76,123,238,185,151,226,151,47,160,240,220,12,38,8,198,150,192,1,112,165,30,28,136,9,124,87,116,76,207,14,33,20,119,59,237,180,147,192,161,43,194,248,100,138,60,202,86,229,176,192,8,175,132,108,194,64,130,113,134,197,145,47,236,96,156,68,224,158,211,164,253,147,58,193,221,188,196,252,100,204,16,108,179,201,24,136,132,140,72,94,169,64,38,249,37,4,64,226,29,154,188,148,27,118,79,1,59,31,158,177,82,188,75,141,97,126,94,238,89,120,162,232,207,246,59,155,175,175,191,119,221,117,55,109,215,40,217,105,210,105,9,156,93,69,13,115,177,23,147,132,85,137,216,61,137,2,53,47,25,188,79,59,237,180,138,215,177,161,178,75,4,170,169,185,138,16,240,141,197,101,118,1,71,65,8,202,224,138,239,233,13,254,108,176,193,199,19,165,148,85,152,55,175,16,244,99,129,164,43,202,42,174,225,3,224,13,229,251,124,192,202,219,101,231,157,117,78,33,116,117,82,178,57,15,61,64,232,12,105,224,64,0,5,47,56,91,180,67,200,104,239,242,43,44,159,171,48,97,254,162,60,195,224,239,43,166,153,131,120,89,231,165,120,190,109,144,63,223,132,206,103,149,74,38,227,152,39,127,94,153,254,179,75,47,189,84,149,210,244,11,190,195,162,14,69,174,237,92,245,243,178,176,34,95,86,49,232,231,225,30,67,211,136,17,35,149,230,216,78,39,158,211,79,60,64,113,254,201,38,57,116,187,130,214,100,243,132,223,229,135,128,26,132,84,46,236,74,241,141,86,180,220,118,8,173,42,252,17,217,11,167,2,174,59,126,122,71,145,71,228,202,125,207,115,118,50,195,107,216,21,97,105,73,81,62,195,251,242,240,49,230,125,233,62,72,184,35,229,85,89,165,81,204,251,98,249,207,202,102,231,4,115,133,53,13,14,71,217,132,204,200,251,172,65,200,248,113,94,155,152,35,124,99,252,88,229,53,249,205,179,34,103,169,108,189,246,187,87,198,136,121,48,70,165,83,79,61,85,29,54,44,143,127,53,186,226,175,157,252,247,118,175,138,58,25,127,224,103,41,150,79,92,174,60,168,114,176,200,131,147,50,202,68,251,182,89,87,214,112,140,63,242,72,167,27,132,26,49,40,128,255,200,34,208,110,75,166,100,101,221,196,110,49,63,153,49,96,57,137,6,96,201,20,117,190,35,0,107,240,149,86,90,73,97,138,177,51,155,112,170,195,128,9,188,143,59,238,184,228,245,82,75,47,85,213,32,4,254,103,215,63,54,39,242,100,84,57,63,54,53,39,146,138,26,184,81,131,144,236,148,202,166,145,35,71,85,85,128,250,249,209,111,128,95,102,92,221,108,179,205,53,58,1,158,236,217,164,227,39,112,201,242,238,108,62,126,199,227,231,50,227,23,239,214,195,120,151,85,100,234,248,73,217,203,44,211,59,126,148,99,114,68,209,122,152,122,44,65,87,160,41,121,78,152,208,64,158,87,93,63,174,55,211,138,74,174,40,60,129,15,107,130,78,78,106,16,146,254,211,151,78,221,33,4,252,81,186,51,198,232,221,178,233,224,131,15,214,119,126,100,20,242,176,163,99,120,85,126,217,203,155,200,175,107,79,193,69,116,7,89,154,11,62,230,213,127,219,109,183,69,240,57,116,120,36,219,153,234,243,29,83,178,99,104,202,51,76,170,156,45,6,100,162,131,24,191,71,38,53,250,159,231,64,98,14,18,89,167,14,109,68,7,252,99,6,33,232,109,158,78,180,25,93,64,151,146,103,16,98,55,162,201,239,243,47,48,127,74,159,53,125,201,90,50,86,47,206,40,109,145,246,103,113,210,112,194,244,191,53,229,137,121,230,22,30,210,171,87,51,57,137,241,199,137,200,79,22,153,71,206,61,242,31,235,61,60,140,111,88,247,89,138,121,209,240,92,153,81,97,32,237,55,249,140,111,208,221,64,47,243,104,5,229,35,255,81,7,14,4,205,78,24,202,76,255,18,12,66,125,128,174,25,27,194,14,161,234,64,68,96,178,29,66,108,73,158,50,101,94,181,6,251,196,155,18,84,249,39,198,32,22,71,36,51,8,225,169,84,79,50,98,3,97,32,225,53,15,51,97,215,66,81,146,115,141,116,162,249,91,182,97,46,124,231,183,111,203,79,110,169,249,32,26,217,68,59,241,26,204,243,162,200,230,29,108,191,213,32,212,35,24,181,203,32,4,241,38,116,32,127,236,84,65,200,212,133,190,16,97,22,6,245,36,12,54,132,111,91,99,205,53,146,236,120,178,64,148,235,193,1,219,122,140,65,136,133,190,110,169,151,250,89,224,251,198,32,10,71,113,6,65,134,240,231,37,118,35,225,209,193,86,91,75,75,202,78,165,106,30,116,150,175,232,106,138,249,188,29,66,124,131,135,3,12,106,195,141,42,231,222,33,135,28,162,239,48,144,89,50,129,204,247,24,180,119,92,89,80,78,150,240,38,120,211,153,18,145,133,35,240,44,234,247,1,7,28,160,112,193,195,176,85,201,118,8,141,30,211,89,33,227,12,30,224,210,5,23,92,160,120,10,44,249,195,160,142,224,234,43,147,201,111,2,18,10,157,108,98,161,7,142,249,116,208,242,64,7,121,87,20,186,2,33,30,252,197,171,170,86,162,189,93,226,101,181,198,26,189,243,74,21,9,242,253,82,75,45,157,251,249,116,241,102,164,126,188,138,179,137,112,113,244,57,175,79,217,188,101,250,109,99,65,219,131,65,168,76,35,211,247,182,152,99,10,70,237,188,180,253,246,226,205,43,227,46,231,120,228,189,214,103,177,44,19,135,47,176,76,121,94,209,246,174,232,138,188,5,31,147,115,32,82,89,140,94,251,50,78,42,67,206,15,232,52,11,116,60,60,225,13,244,97,33,9,89,9,253,241,147,45,170,253,16,64,254,123,238,81,240,178,104,100,161,227,47,236,104,15,229,238,232,57,98,248,223,42,173,145,247,171,173,182,186,255,56,220,119,24,4,252,29,66,254,194,184,21,221,48,131,16,60,10,175,223,97,195,134,235,206,7,118,189,37,127,226,161,60,98,248,8,197,61,240,207,12,148,24,76,193,245,237,183,219,62,183,105,9,62,174,94,155,247,49,23,193,247,213,87,239,229,125,230,193,76,184,146,188,132,114,131,250,135,202,28,182,100,109,242,157,107,236,29,87,230,22,125,176,53,87,92,70,188,67,35,107,164,242,191,43,186,71,94,195,107,149,93,6,148,203,31,52,133,144,199,6,39,251,214,232,74,53,67,51,187,125,41,3,229,184,111,4,83,57,88,158,23,201,131,22,78,150,112,68,173,74,56,6,210,54,214,127,89,229,100,171,234,108,85,185,182,254,133,223,212,74,38,255,249,59,76,54,103,23,169,204,153,60,197,40,229,77,155,54,77,29,23,172,108,51,8,249,142,0,177,81,170,43,215,153,199,190,211,112,103,82,143,239,253,188,172,120,244,79,152,48,209,178,84,92,179,235,159,120,78,20,27,79,112,8,164,47,224,240,156,38,28,52,138,66,198,125,180,251,163,117,21,27,27,110,186,34,66,118,147,152,163,139,46,186,104,238,183,102,16,42,154,231,254,71,113,185,89,131,208,102,138,199,23,94,120,161,159,53,185,103,183,146,156,185,156,252,174,118,131,193,138,117,133,47,183,107,180,22,129,41,101,100,13,72,230,109,159,167,187,193,144,192,28,203,51,22,153,227,109,158,172,95,173,125,101,123,103,33,227,160,35,121,74,222,178,181,183,168,61,68,210,129,255,204,218,109,86,42,11,60,129,80,162,28,221,224,59,62,217,60,44,90,43,234,60,148,242,252,181,162,226,174,224,17,186,146,108,138,117,4,93,81,158,34,222,207,107,124,199,151,103,49,164,2,255,106,114,182,57,51,18,109,130,100,120,187,168,236,90,244,121,147,213,69,40,57,112,151,157,242,157,152,226,40,57,177,236,222,42,131,16,50,22,127,132,241,67,103,198,174,97,12,30,56,185,1,187,69,22,89,52,242,249,140,226,140,140,127,145,225,27,156,97,253,111,242,140,225,68,45,163,28,235,15,198,191,72,158,80,253,146,188,55,121,34,145,147,132,158,101,229,36,116,137,180,29,60,203,38,162,89,193,91,152,43,164,90,115,192,228,51,227,69,186,147,87,190,39,116,98,81,218,81,28,151,168,223,231,145,69,121,27,125,110,6,33,96,124,238,185,231,54,250,121,219,242,15,19,0,148,58,9,36,74,221,190,242,52,78,14,172,236,129,21,7,107,125,225,11,123,56,177,192,58,81,230,57,81,118,39,205,148,93,63,154,207,14,20,212,111,4,196,246,109,146,81,110,132,33,233,129,117,178,149,211,201,162,196,137,81,70,15,162,19,2,224,100,194,105,86,217,114,167,215,153,51,243,15,166,228,165,40,111,156,8,33,122,168,161,102,214,127,40,37,93,239,236,103,103,235,225,98,178,245,84,223,249,255,136,231,80,234,80,101,255,93,184,7,2,237,155,39,140,220,121,231,157,231,206,59,255,60,5,61,172,175,75,14,52,20,139,189,19,239,63,39,139,74,125,158,253,71,20,20,122,224,156,108,213,116,66,208,245,64,211,225,195,135,185,87,254,25,227,18,249,69,193,174,7,18,214,131,3,34,60,75,197,78,15,92,20,3,149,226,250,246,59,236,224,68,80,212,195,117,253,250,197,248,162,32,2,111,69,120,76,94,129,247,148,195,149,255,196,139,37,121,199,7,121,243,194,203,80,245,182,214,183,18,102,64,14,35,95,222,221,117,231,93,90,175,108,27,215,242,152,119,244,97,226,196,9,78,20,2,233,58,164,191,69,7,149,138,33,200,173,180,210,202,238,142,219,111,215,131,134,37,212,137,206,87,10,160,223,28,66,158,109,147,254,150,241,179,121,156,174,172,185,191,132,25,54,183,192,54,149,38,158,203,78,194,171,232,31,248,33,66,146,19,143,45,119,227,143,111,116,191,185,255,55,238,190,95,223,231,100,225,158,106,141,226,102,234,137,160,42,120,38,255,113,152,104,54,129,159,188,147,5,113,10,63,201,199,24,241,173,132,121,112,208,226,108,18,47,44,61,148,212,230,149,24,132,220,200,81,35,244,32,200,84,94,25,231,25,51,150,75,61,178,31,243,206,59,197,61,254,248,99,185,7,114,115,136,35,73,148,239,150,189,35,174,89,92,239,136,70,135,70,214,15,1,33,39,121,243,140,2,158,122,234,73,45,71,188,47,11,203,67,46,129,198,63,245,212,83,73,30,9,53,144,220,23,221,100,231,155,40,161,221,136,17,195,43,230,199,156,224,159,132,241,113,178,96,80,250,34,10,45,39,139,99,119,245,53,87,235,193,244,226,149,237,68,209,171,205,210,126,211,255,33,249,52,85,28,103,156,56,70,232,33,212,124,227,243,12,229,133,66,79,134,143,24,225,36,212,74,10,134,74,163,132,222,72,104,9,161,53,79,23,129,32,60,239,0,8,204,9,254,245,181,91,23,93,120,145,147,157,109,85,139,145,93,17,238,214,219,110,75,100,17,14,188,102,30,74,148,131,66,25,69,241,241,233,103,42,202,205,159,139,35,220,171,175,246,202,148,18,14,82,15,193,206,227,187,20,136,220,42,225,88,157,40,186,146,242,173,77,162,116,169,152,35,150,137,54,177,102,241,211,242,203,175,224,36,36,137,255,168,174,123,49,98,233,28,151,176,43,42,11,154,140,33,222,198,238,87,191,254,149,251,205,125,191,169,75,198,160,50,113,126,112,95,249,234,87,156,156,73,163,235,46,159,166,233,220,151,60,38,7,155,108,97,141,180,188,121,114,134,229,233,235,85,241,82,232,143,32,64,130,3,125,45,179,191,190,239,229,63,34,92,213,72,74,91,145,242,164,223,150,36,198,6,168,47,114,251,74,246,40,117,229,128,237,167,133,14,203,238,19,149,13,121,153,165,248,200,125,20,18,243,179,212,231,201,15,112,95,28,100,146,223,220,208,14,173,63,245,212,255,145,110,171,206,9,169,156,117,134,191,134,242,191,24,59,118,156,240,141,103,252,71,13,221,27,254,229,126,212,11,182,220,215,246,80,28,71,5,72,145,30,24,206,51,49,58,86,28,108,111,121,117,44,164,92,127,76,236,93,238,53,3,124,227,191,18,157,37,55,187,40,244,21,30,254,248,89,70,104,151,40,82,117,237,101,235,97,14,66,103,110,90,178,118,113,240,187,24,133,236,177,94,169,115,197,149,86,116,63,23,57,129,117,137,173,31,69,201,238,196,16,164,135,191,139,49,60,245,13,63,196,217,4,193,73,225,82,241,178,131,30,152,12,196,252,233,228,196,24,73,136,113,119,221,15,175,115,103,157,125,150,234,63,232,143,56,148,58,112,25,29,128,156,43,155,116,49,230,77,78,243,229,205,67,224,50,118,220,152,202,53,189,192,41,143,70,136,81,193,137,177,198,137,67,173,147,48,170,90,159,56,55,41,207,76,42,181,155,12,254,63,245,215,88,118,174,38,103,203,174,14,39,97,195,28,124,152,164,56,45,109,156,33,56,157,55,223,153,51,36,9,133,170,215,142,252,7,165,88,11,241,146,49,70,79,132,252,65,85,175,137,62,13,29,237,2,162,243,185,240,251,23,58,57,187,76,101,120,131,157,226,140,228,203,210,110,198,66,231,145,100,28,51,118,76,162,255,50,156,144,99,22,84,254,217,118,219,109,93,30,78,252,241,79,200,110,189,242,4,247,148,71,185,70,187,120,150,229,9,203,175,80,41,39,137,33,220,201,49,6,78,162,34,232,216,75,36,21,62,117,232,51,196,16,228,38,204,51,193,137,17,84,159,25,47,146,157,82,21,188,200,234,71,103,108,122,45,197,61,233,63,184,88,148,214,249,216,58,186,214,42,122,223,231,231,82,191,64,37,5,151,62,151,217,228,2,74,111,16,210,254,10,32,51,116,168,201,96,232,252,226,108,82,91,79,196,203,212,201,78,2,39,7,11,58,177,210,234,36,69,113,33,158,72,110,193,5,23,112,98,85,214,172,217,239,236,123,9,139,228,196,35,92,137,12,207,228,0,122,55,247,60,243,56,137,47,154,162,115,48,44,25,30,39,91,81,237,211,138,43,138,105,4,144,116,98,106,196,196,195,158,207,158,61,219,205,215,67,4,236,89,184,150,15,2,140,155,196,13,117,226,117,166,196,13,65,85,188,19,10,23,194,40,220,190,116,240,193,238,214,91,110,113,31,138,176,202,100,150,131,45,53,191,120,69,165,58,56,91,22,19,213,112,201,207,172,184,43,141,193,240,137,16,76,250,64,112,60,79,200,120,232,225,135,245,253,122,51,103,106,253,222,154,76,159,27,129,73,27,132,226,87,115,250,111,60,183,178,120,159,46,77,14,51,119,18,82,78,141,89,24,211,72,226,77,161,12,81,188,47,18,225,48,249,74,250,203,66,191,40,205,59,101,138,190,98,177,193,188,19,207,4,237,218,204,245,214,67,18,139,187,41,77,202,246,31,67,92,75,83,197,252,111,105,109,45,43,156,69,151,120,223,41,77,221,121,231,93,196,56,116,173,19,143,87,21,88,234,169,20,108,48,129,215,207,207,56,145,46,19,193,7,225,39,155,248,142,121,135,81,62,86,64,143,80,1,91,60,69,157,236,106,75,132,12,51,156,255,231,223,239,37,130,158,95,86,209,220,66,185,69,242,23,30,246,29,10,46,173,63,139,52,150,161,164,87,155,127,152,225,66,26,88,16,0,31,213,199,188,160,91,240,28,112,217,240,58,47,155,205,5,22,82,73,130,70,22,208,42,229,99,95,250,146,210,103,217,170,44,88,213,37,78,42,163,181,14,217,157,153,20,97,55,134,127,246,187,145,43,78,61,27,111,188,177,254,33,191,125,98,163,141,156,120,76,170,210,88,194,211,196,69,169,111,94,126,169,178,11,209,201,14,90,135,178,65,188,235,82,153,148,214,72,63,113,58,224,79,83,15,129,49,58,195,51,159,214,196,153,194,191,157,4,1,195,191,118,208,191,162,57,147,7,47,157,94,30,47,81,124,20,196,3,23,47,151,191,60,106,13,94,250,248,200,92,60,248,224,67,132,247,221,164,14,65,212,3,239,99,190,163,124,245,19,178,205,164,201,147,115,229,66,203,39,187,18,82,6,161,132,31,247,204,17,127,94,240,77,252,187,43,105,147,245,127,1,81,224,247,53,249,50,6,70,93,57,99,179,66,198,160,126,171,211,175,143,245,152,120,1,187,97,67,134,234,119,114,14,132,255,58,150,7,229,99,9,69,156,122,222,211,33,189,240,162,229,242,160,140,63,227,156,215,135,116,195,202,255,43,15,95,243,90,205,26,133,113,243,147,245,31,252,203,75,106,92,148,10,124,229,90,182,62,27,43,115,220,201,43,71,215,224,153,23,141,194,63,230,27,254,60,141,103,65,166,88,247,238,59,239,36,50,42,124,81,206,102,112,31,194,87,201,200,188,151,27,46,172,211,100,215,75,122,141,67,190,28,254,155,133,91,182,78,255,55,142,19,40,73,173,207,232,44,230,153,48,193,207,146,220,91,93,62,124,147,151,153,27,93,99,2,52,63,201,111,30,21,173,201,242,100,103,95,142,192,113,131,132,50,22,135,175,247,50,180,75,95,210,151,30,37,185,254,246,254,217,99,247,61,116,253,40,225,102,157,236,120,214,55,178,243,199,189,44,202,244,3,243,214,143,146,67,194,0,234,0,64,79,59,57,233,216,245,192,223,198,177,19,251,3,223,146,29,106,78,206,117,117,178,211,198,201,110,30,237,134,173,3,103,205,154,149,234,22,243,144,249,112,217,101,151,247,202,111,169,28,49,127,122,247,157,222,181,162,76,42,205,145,183,246,148,48,225,170,23,68,78,60,85,244,126,232,254,224,27,240,17,137,246,226,82,180,9,100,247,210,83,79,62,229,38,214,35,103,75,253,89,57,59,85,174,87,166,25,62,235,153,147,222,103,165,185,101,78,183,216,30,164,227,191,240,194,31,113,15,254,249,65,237,55,6,101,28,91,94,236,209,251,100,215,61,38,207,32,95,93,126,185,200,88,153,113,212,2,229,217,191,122,244,11,62,78,96,44,60,77,254,144,161,178,56,241,208,131,15,41,253,203,202,19,96,91,92,69,236,6,108,60,138,198,130,138,69,114,146,68,147,113,18,29,71,29,89,100,151,146,246,77,13,68,226,76,190,191,172,131,48,152,147,98,94,212,37,250,18,89,195,200,95,54,89,253,255,250,215,191,149,23,89,253,102,100,202,230,231,55,248,24,207,146,188,183,205,121,214,234,242,251,218,202,97,125,45,160,93,223,35,80,132,84,12,1,37,158,30,140,88,84,200,214,59,39,241,179,85,49,32,33,226,156,108,9,85,175,16,20,152,120,189,251,201,103,168,40,216,101,155,167,91,98,250,18,78,182,66,59,9,59,224,152,72,40,41,240,94,221,103,223,125,18,1,213,148,239,166,144,247,203,180,123,217,26,40,4,178,182,101,148,242,223,251,207,251,246,89,184,54,8,129,182,17,27,169,136,29,60,120,17,212,74,24,124,176,234,63,248,231,63,187,61,197,72,137,112,3,227,98,145,64,154,111,190,244,2,122,248,136,145,46,107,36,42,170,195,4,6,112,15,97,230,215,178,243,71,182,235,170,226,12,166,226,167,113,34,116,189,35,120,232,123,212,128,243,86,6,247,48,114,95,72,49,239,47,191,156,198,239,171,227,61,134,181,67,15,61,84,13,66,8,244,180,227,98,241,10,39,177,235,41,157,226,17,206,83,62,90,62,188,41,72,8,153,36,4,3,230,31,253,246,231,56,239,252,254,251,253,230,93,51,19,48,174,103,254,55,179,206,86,151,5,173,250,222,247,206,85,131,144,143,83,86,111,22,214,60,7,14,112,177,172,176,198,59,243,42,222,87,140,131,114,206,149,142,141,63,62,10,67,193,13,232,173,210,73,89,104,51,175,36,100,137,195,248,207,188,146,112,87,137,87,36,158,165,126,242,241,220,127,110,247,121,237,181,119,214,110,251,221,89,215,24,230,214,255,206,106,123,104,109,17,4,98,121,176,152,182,178,168,244,61,254,243,202,193,195,142,165,51,94,115,150,80,91,229,225,10,52,87,194,2,201,124,251,163,240,177,61,157,132,247,112,18,199,221,227,99,226,16,227,201,95,86,30,203,162,188,242,122,223,215,190,91,107,173,181,220,238,178,115,224,244,211,207,80,15,78,12,66,113,153,249,101,75,248,79,245,200,36,31,14,64,217,100,244,7,71,4,188,66,73,204,127,93,200,202,149,178,249,205,174,5,104,77,72,157,12,129,246,208,63,197,153,58,193,100,211,196,120,142,226,163,48,70,188,164,217,93,100,248,199,251,24,207,99,222,105,248,200,92,132,247,73,184,39,149,145,216,189,235,203,148,240,62,43,155,38,193,51,63,212,185,94,220,64,202,180,186,200,165,109,18,113,107,191,125,227,57,98,109,226,157,229,163,14,254,152,35,250,222,190,35,83,19,18,229,178,19,95,206,252,83,47,93,43,146,17,69,142,176,118,216,115,28,69,80,44,190,252,242,203,34,155,124,207,73,248,23,123,149,92,233,151,156,51,144,200,131,86,6,253,240,231,127,43,229,193,164,49,3,224,198,228,54,221,149,82,163,63,56,155,49,110,105,195,77,44,211,103,215,227,217,162,108,156,244,185,124,226,255,182,53,56,227,87,148,138,148,255,54,23,243,190,123,239,63,105,39,7,227,27,204,83,248,6,56,67,59,184,146,236,222,230,41,207,232,151,132,140,231,182,34,241,93,182,223,69,252,55,230,247,113,61,21,5,121,15,160,9,224,63,244,192,148,127,240,247,119,101,13,148,151,76,249,76,244,138,90,233,185,231,158,215,44,114,176,122,146,213,198,193,198,32,121,225,221,248,115,149,181,45,74,85,95,110,247,105,23,235,97,43,211,43,194,141,238,89,207,249,207,184,7,182,172,31,225,243,232,108,128,41,198,33,234,196,217,48,47,49,255,73,166,92,205,203,211,9,207,124,56,249,247,157,208,246,108,27,81,132,99,16,194,8,132,65,136,249,122,195,141,55,40,14,111,178,201,38,169,236,204,67,198,119,191,253,246,77,214,138,100,0,6,140,191,205,71,174,38,191,177,254,38,217,28,214,31,222,63,204,103,234,189,247,222,123,117,135,6,186,194,115,206,61,71,157,159,216,69,30,243,131,222,121,110,159,82,30,70,221,106,9,190,68,253,236,182,245,83,118,238,219,59,27,75,235,135,61,239,148,43,180,32,134,118,235,90,12,61,244,119,119,202,209,6,186,203,11,122,192,46,99,118,208,248,240,182,113,71,191,224,203,252,62,172,225,31,62,237,38,31,78,223,236,56,150,35,66,220,181,215,94,231,228,252,27,119,203,173,183,184,123,239,185,87,141,224,232,153,76,158,200,226,159,149,205,213,140,243,64,4,84,180,246,100,33,196,142,36,57,246,66,105,152,25,132,208,65,3,79,250,101,41,214,111,69,137,204,200,243,188,250,25,11,230,128,209,231,106,122,234,120,179,67,175,204,105,117,53,227,154,192,162,25,133,181,176,140,180,85,160,133,21,245,173,232,94,34,215,183,114,6,238,215,16,207,44,17,98,193,143,65,72,98,83,59,12,66,44,18,228,112,73,13,125,148,133,132,33,44,207,207,58,235,44,37,38,119,254,236,206,148,130,156,119,186,131,66,42,50,98,61,109,218,52,30,39,91,13,245,71,230,31,182,11,102,219,70,150,172,120,215,221,221,237,8,105,192,164,133,48,133,212,24,4,16,166,109,92,26,251,178,193,220,222,248,215,250,18,6,130,144,206,34,2,188,242,19,140,228,181,215,94,149,173,240,189,33,54,62,242,145,133,149,153,213,131,3,214,87,20,2,132,197,193,11,128,109,244,71,28,121,132,147,248,185,169,237,209,31,21,220,122,78,60,193,81,154,155,49,202,111,75,222,125,244,97,30,214,230,229,172,254,204,218,153,151,107,238,185,231,214,5,2,66,60,33,221,104,31,30,94,108,207,37,124,80,58,49,194,241,92,179,121,151,126,223,51,15,37,147,156,29,161,175,152,83,120,230,248,139,142,236,55,173,254,77,255,155,3,201,86,183,52,93,62,94,40,8,67,24,104,108,225,232,231,32,244,2,139,78,66,82,88,210,177,22,248,23,45,206,25,63,159,214,218,119,54,94,8,113,224,110,173,132,97,254,79,127,254,83,238,188,98,49,65,216,9,83,86,80,86,53,28,228,125,94,155,120,62,80,82,173,254,15,148,126,14,150,126,216,60,43,26,215,197,22,91,76,22,45,247,104,232,76,219,9,148,133,77,28,194,34,114,201,142,27,205,144,79,169,116,190,137,241,53,143,143,49,223,240,208,243,231,155,95,87,81,27,45,15,11,17,22,92,44,114,178,139,127,203,131,241,137,244,230,155,111,234,181,168,255,200,90,187,124,102,23,85,246,160,72,206,227,117,240,4,18,11,165,60,165,177,190,12,255,12,40,8,212,194,193,190,118,150,242,235,149,63,141,215,24,143,52,124,68,65,89,15,62,50,23,145,41,89,223,156,121,230,153,169,166,51,151,94,21,153,210,87,56,44,178,200,34,78,206,220,210,232,6,230,40,227,127,68,59,88,215,152,210,128,119,218,38,33,5,240,227,122,218,212,72,255,253,186,235,147,49,230,19,57,249,181,228,51,145,242,245,62,59,166,135,31,126,184,26,122,80,228,84,58,19,197,159,79,147,185,143,60,216,136,28,156,84,220,228,155,184,23,77,46,180,205,197,129,39,24,28,216,245,81,45,129,99,79,60,241,132,27,39,10,212,180,177,45,230,55,54,39,242,203,200,172,235,228,19,127,236,109,254,164,60,240,51,5,17,125,35,155,70,8,253,127,235,173,55,53,244,80,86,57,139,179,196,115,207,62,151,146,123,169,135,49,163,191,245,200,168,212,71,185,23,247,56,184,101,235,207,255,157,207,127,227,254,230,191,243,203,81,37,162,52,210,118,89,240,142,221,14,175,120,50,186,159,31,185,155,254,48,54,213,82,60,126,143,235,248,249,187,129,108,28,236,90,84,134,189,103,61,140,49,40,79,142,128,118,101,215,195,113,121,153,241,247,42,97,183,15,6,38,214,143,40,238,89,51,254,228,166,159,56,194,47,229,133,93,231,83,91,175,160,68,238,228,100,48,165,15,254,125,39,246,105,237,181,215,118,139,47,190,184,26,99,8,205,205,174,136,119,222,126,199,237,249,133,61,43,140,166,54,223,27,153,135,181,103,78,108,32,196,249,155,63,162,11,129,163,56,36,176,115,247,136,35,142,16,176,198,250,7,31,214,240,17,57,155,47,21,226,43,11,127,100,82,234,55,57,219,104,157,241,255,108,126,251,109,249,236,119,167,92,173,221,208,202,86,37,198,192,31,7,234,97,55,49,71,115,220,36,187,166,229,172,40,39,231,58,38,213,27,206,212,43,207,216,135,224,152,225,4,58,54,195,9,66,82,130,19,211,166,77,115,47,188,240,130,234,151,242,116,36,86,78,189,87,140,237,68,175,34,84,46,178,17,107,183,155,110,186,89,249,205,140,25,51,146,98,168,23,102,68,251,234,145,207,144,1,73,213,34,0,197,239,4,199,5,182,205,78,86,38,37,27,126,52,187,142,102,148,87,59,96,122,51,106,233,115,25,49,33,234,115,49,3,184,0,124,198,12,233,172,155,76,228,197,22,91,220,253,228,39,63,86,101,51,2,195,102,178,107,200,98,205,90,62,174,246,45,138,13,188,157,200,147,22,92,227,220,196,53,213,153,24,255,212,133,5,183,196,63,197,19,32,155,32,250,63,248,193,165,217,199,50,151,43,149,196,76,90,12,1,40,71,178,73,14,72,211,80,77,196,213,15,41,13,1,37,48,74,195,240,26,168,135,245,167,191,111,252,87,253,4,19,165,27,244,21,129,39,155,240,70,177,29,45,246,14,69,94,45,28,144,3,178,53,123,220,239,174,196,251,0,65,29,193,248,195,255,125,168,158,13,126,12,90,51,174,224,249,146,151,30,121,228,17,21,108,82,239,164,221,125,135,103,109,88,153,231,3,231,125,193,208,129,73,145,119,23,163,91,212,7,96,141,226,99,113,153,243,166,16,65,145,8,252,175,189,246,218,84,215,236,7,49,172,49,122,180,52,213,6,65,75,171,159,211,194,49,164,115,30,22,138,213,188,132,114,246,159,98,120,241,233,169,226,75,149,41,200,43,95,241,100,229,98,176,131,6,35,8,101,231,132,229,65,8,51,111,172,56,38,110,151,99,247,64,54,49,175,226,221,15,189,111,140,190,247,62,73,223,213,124,159,206,222,65,191,16,156,123,96,48,113,101,0,0,64,0,73,68,65,84,249,91,7,53,60,52,181,22,4,8,153,86,144,56,147,129,185,118,193,5,23,20,228,112,137,162,106,5,137,103,237,167,60,154,255,55,141,127,30,229,206,55,22,196,239,127,32,94,144,32,90,69,202,123,150,206,132,99,4,10,172,125,246,233,221,121,157,206,193,153,72,40,28,35,93,128,37,239,180,255,189,229,179,203,129,16,113,175,191,246,186,246,187,72,33,4,173,25,42,33,165,216,77,91,15,173,73,234,11,55,29,8,129,246,208,191,120,206,212,39,127,194,255,144,255,109,190,160,84,194,1,140,208,104,245,224,99,124,102,138,83,167,153,236,128,48,23,63,120,255,131,164,108,222,47,185,212,146,154,173,72,6,130,191,19,102,206,87,80,197,109,26,82,55,63,110,164,255,126,155,77,198,128,239,231,37,100,140,151,95,126,201,117,247,56,248,144,167,171,43,94,182,251,116,234,234,171,175,118,167,157,118,154,158,1,136,193,172,40,45,217,99,88,46,146,33,219,33,15,50,238,252,87,69,76,42,106,126,233,158,131,203,200,216,47,201,24,21,193,148,70,227,229,204,218,122,37,113,88,51,188,247,59,147,247,172,247,125,22,82,189,52,159,60,170,104,149,71,208,115,31,135,237,123,240,228,202,43,175,180,159,201,117,65,9,145,67,126,59,103,33,121,33,55,172,193,63,252,48,14,195,109,207,153,19,156,21,123,195,13,55,86,157,167,68,36,104,118,74,247,56,191,116,66,170,178,54,156,95,118,217,16,102,213,210,228,201,147,212,49,36,15,54,140,31,107,67,118,21,49,135,138,18,187,55,242,199,47,110,153,63,23,179,101,248,242,103,236,132,226,114,229,136,187,239,190,187,0,174,213,245,95,56,68,202,116,82,197,61,107,4,232,95,145,65,152,182,161,223,97,254,165,119,170,101,91,93,254,223,10,243,30,153,171,26,252,203,223,147,184,133,236,142,96,221,198,249,113,224,34,93,219,85,118,204,102,19,242,27,120,251,163,31,213,183,86,228,251,106,244,5,124,64,169,239,39,248,177,157,51,142,110,196,18,148,200,47,107,197,21,87,210,87,240,177,162,116,241,197,23,233,43,147,179,179,252,191,232,187,78,125,110,240,201,194,170,217,253,201,83,245,225,116,61,126,220,120,247,237,111,127,59,57,63,154,122,13,103,144,51,178,186,1,107,23,134,63,211,47,128,19,89,7,131,94,156,232,210,51,139,249,110,169,165,98,167,229,34,218,9,238,228,233,151,170,209,115,165,103,82,54,237,129,111,125,32,107,171,172,62,12,94,52,164,107,168,187,94,120,94,158,222,153,182,249,250,18,115,168,67,198,204,163,21,60,35,127,171,146,143,19,224,127,89,83,121,91,102,16,3,115,228,47,132,140,51,128,228,95,37,152,80,197,11,144,112,159,125,246,118,239,75,24,182,205,55,223,2,48,170,210,161,50,163,60,233,145,57,241,56,193,210,139,2,130,88,188,126,58,225,132,19,84,225,156,100,150,151,221,221,221,122,8,221,11,207,255,93,99,216,250,147,141,123,44,213,143,63,70,57,178,0,240,40,216,135,28,166,153,73,198,128,56,128,206,182,53,91,150,3,15,60,80,207,52,178,88,144,246,60,92,123,20,204,85,148,99,205,135,81,15,178,212,81,176,42,203,37,59,59,213,252,196,56,226,109,160,9,196,236,73,132,191,34,129,107,217,48,7,156,151,194,185,86,41,111,55,193,41,35,182,124,135,135,53,158,11,48,52,60,38,48,46,145,248,118,136,204,135,175,127,253,235,201,225,134,250,66,254,193,131,101,163,13,55,114,235,175,191,126,194,232,120,55,207,220,243,184,55,197,131,46,43,44,217,119,245,93,107,195,138,131,30,151,156,190,164,26,30,216,250,207,174,33,223,195,45,91,15,194,23,198,93,63,161,12,196,59,142,254,198,222,60,241,91,158,13,17,5,194,113,199,29,95,225,197,8,28,49,26,175,183,254,122,169,126,251,229,54,229,94,65,32,131,236,205,255,166,148,219,226,66,8,231,7,209,252,234,215,190,154,198,57,169,23,56,3,91,206,196,242,15,212,100,236,248,198,23,162,147,102,246,244,223,167,131,246,142,45,213,108,207,6,23,143,63,254,120,123,156,92,25,211,207,124,230,51,137,96,20,27,161,34,49,246,255,36,201,195,13,66,220,222,66,243,179,137,58,153,102,254,92,73,229,169,129,166,188,46,252,54,85,80,217,126,72,203,249,191,195,112,175,108,80,44,103,123,138,145,150,176,3,200,49,40,137,56,40,55,155,80,208,113,86,27,134,163,173,182,218,42,121,205,252,69,9,155,165,249,11,245,156,219,150,55,223,216,169,80,124,158,81,113,27,173,82,20,51,27,126,124,67,157,251,199,30,123,108,5,174,62,44,231,223,225,89,60,122,244,104,61,171,207,190,83,196,54,193,77,30,210,14,66,69,160,12,131,247,21,37,104,205,246,59,108,175,245,29,119,220,113,21,217,136,27,15,173,169,166,84,170,248,40,60,40,41,4,218,67,255,26,225,13,208,98,223,129,13,199,179,29,119,216,81,121,108,30,62,30,121,228,145,41,124,52,71,181,188,185,136,81,85,25,157,55,26,95,250,34,177,232,187,220,9,34,251,33,23,250,9,175,208,175,29,37,161,122,229,63,20,198,198,39,180,77,59,10,63,158,253,140,200,78,149,115,196,218,100,138,138,70,250,239,215,175,225,180,132,49,127,245,43,95,173,240,94,165,61,42,99,200,90,105,61,145,77,45,101,21,245,143,61,246,152,200,5,123,234,217,32,24,183,170,133,130,226,252,67,20,18,244,201,12,107,86,46,178,7,242,96,86,14,182,247,205,186,218,248,55,171,188,254,46,7,154,13,253,39,76,245,239,126,247,187,138,230,112,150,219,17,71,28,169,235,143,147,79,62,185,226,61,248,106,120,87,241,82,222,85,190,79,243,20,118,22,108,33,235,123,214,235,156,247,144,77,120,251,63,252,240,95,40,38,37,195,153,195,192,25,103,156,145,250,132,221,229,200,155,136,76,255,243,140,66,241,156,216,81,12,72,127,171,58,39,204,193,45,85,104,3,63,242,230,18,250,159,188,231,20,139,174,98,179,205,54,211,208,105,236,122,133,183,251,103,97,174,178,202,170,194,211,223,210,157,57,121,205,64,71,193,252,39,244,90,222,248,221,113,199,29,10,15,230,13,138,214,116,138,199,162,168,109,154,23,18,220,35,127,90,36,128,236,122,24,185,221,214,195,21,101,201,192,85,211,127,113,80,250,146,211,151,82,131,58,235,199,185,230,158,171,234,250,17,5,237,208,97,67,157,41,232,211,253,233,176,95,61,112,173,128,89,135,117,131,230,178,179,19,28,195,169,21,154,177,210,74,43,187,229,150,91,174,162,39,200,111,232,7,158,121,230,233,170,243,208,120,19,5,128,127,217,249,207,115,240,110,97,137,202,178,238,199,214,213,29,180,60,179,68,232,97,62,50,101,186,61,247,13,171,95,254,242,225,42,103,127,231,59,167,230,202,217,224,227,45,55,35,103,175,236,62,245,169,79,105,17,70,255,139,198,204,158,219,213,234,237,148,171,205,117,218,235,223,55,191,253,105,62,64,249,232,5,208,157,161,159,32,12,161,57,216,40,206,72,56,89,120,188,242,171,76,99,144,103,48,72,130,51,172,125,112,174,230,92,32,118,45,250,137,53,147,244,42,193,137,47,125,73,244,106,130,179,95,255,250,9,185,122,181,13,55,220,208,173,191,94,175,126,201,198,180,26,61,219,116,211,77,245,156,101,28,120,46,187,252,50,55,78,34,8,101,245,97,49,47,146,254,60,253,180,234,244,252,54,114,159,149,207,208,83,111,37,248,135,204,195,78,167,108,130,174,179,206,34,153,206,48,155,167,47,191,109,254,81,70,107,113,162,47,173,148,29,189,125,251,188,13,95,131,243,242,103,136,212,134,26,59,178,10,63,158,164,223,1,60,12,56,155,228,141,55,94,87,227,13,161,227,252,164,112,69,96,1,200,146,248,141,50,129,173,162,44,14,32,226,40,44,240,58,199,251,14,69,1,150,91,127,60,80,178,243,254,219,39,127,91,21,213,28,72,6,210,227,173,195,246,232,99,101,241,161,66,151,148,109,73,191,151,159,126,57,235,9,225,224,220,35,14,73,39,100,22,68,0,130,6,99,66,80,195,19,106,219,109,183,181,34,194,181,7,2,49,129,97,146,180,15,36,254,184,85,171,117,235,173,183,86,6,132,215,11,135,100,35,188,34,132,112,120,34,2,233,7,236,42,139,81,79,139,1,7,16,238,97,60,108,123,7,7,240,104,0,39,30,120,224,1,197,1,226,199,87,75,40,212,9,191,6,254,29,117,212,81,142,51,177,16,106,190,40,10,124,14,76,100,139,41,243,98,218,180,105,26,122,132,178,95,124,241,37,97,34,71,164,194,180,177,117,21,101,34,91,242,213,243,90,60,252,96,152,221,194,92,154,157,118,223,99,119,119,216,225,135,233,118,126,12,163,121,161,77,172,78,230,37,115,236,115,194,192,151,23,24,178,128,67,17,240,240,95,30,214,197,188,197,136,37,63,253,62,72,140,97,244,155,48,15,214,111,230,37,48,126,73,98,103,127,89,22,127,182,131,202,234,104,254,21,252,108,35,130,54,161,3,171,175,190,186,59,240,128,3,229,236,142,211,29,187,23,193,71,4,28,60,82,192,153,135,31,126,72,5,48,95,192,66,153,130,135,206,213,87,93,165,99,136,32,70,216,38,53,116,214,232,63,116,148,29,144,8,116,247,221,119,159,134,249,196,115,153,5,28,207,9,79,103,10,5,232,224,113,199,29,171,222,100,249,243,42,62,75,202,7,3,211,172,72,24,81,250,95,48,60,245,206,117,191,174,50,221,123,228,165,76,205,10,109,233,3,4,192,201,106,211,137,80,3,40,199,152,119,240,28,228,22,248,13,222,203,24,211,241,128,158,60,101,178,134,209,101,65,99,105,203,45,183,116,247,223,127,191,158,81,194,28,35,84,19,101,196,243,237,184,100,190,177,88,122,94,156,26,110,232,225,99,122,238,93,193,252,177,178,171,93,207,56,243,12,183,230,90,107,170,49,24,227,15,139,34,188,250,80,246,226,125,71,249,208,33,11,127,151,237,63,74,171,11,47,186,80,171,96,193,142,226,151,185,206,159,63,127,225,13,192,1,90,243,243,187,127,238,78,20,231,27,120,28,114,33,78,5,120,41,195,55,145,249,42,149,95,213,122,16,222,149,21,2,237,160,127,202,87,26,196,127,159,23,29,119,252,113,238,174,187,239,210,179,175,224,125,240,52,120,31,107,142,44,62,50,23,145,241,126,40,81,9,82,188,239,199,34,83,46,191,130,242,103,31,231,193,247,189,247,222,75,207,63,93,101,149,85,28,142,30,200,126,132,137,186,66,188,66,167,203,60,155,186,238,84,119,207,189,247,232,28,192,240,74,194,104,66,68,4,28,212,108,142,248,109,154,42,115,196,248,241,156,244,159,58,144,41,98,25,227,12,183,200,162,139,184,213,86,93,77,101,12,214,61,132,14,70,73,129,18,217,55,74,249,125,163,12,206,15,124,251,237,183,220,210,203,44,237,76,185,79,30,218,196,31,247,200,14,40,249,161,41,56,71,33,15,174,178,234,42,110,183,93,119,115,221,221,221,186,78,187,245,182,91,221,63,228,80,106,140,233,173,151,7,165,225,130,47,217,190,208,159,78,75,172,145,103,205,218,77,233,47,59,182,89,55,44,187,236,178,138,191,200,217,63,251,217,207,98,165,153,200,117,217,240,54,218,255,106,19,84,133,182,74,56,101,225,6,142,254,242,87,191,84,163,20,115,134,117,20,244,28,252,229,15,167,37,174,254,156,195,129,224,116,217,85,6,206,48,238,200,174,24,76,47,150,16,111,224,4,60,1,126,224,39,230,29,178,40,245,221,47,124,99,35,201,147,204,9,225,39,240,13,155,19,254,119,141,220,251,10,103,251,142,254,210,70,230,62,137,223,28,160,254,176,68,56,176,48,170,11,46,180,160,187,230,234,107,42,118,223,0,11,218,75,95,112,0,201,38,198,111,183,89,189,227,199,217,184,140,31,240,35,52,37,202,249,88,233,249,245,194,80,121,62,92,253,242,117,14,122,15,88,15,163,11,193,83,29,218,133,28,129,115,36,235,225,21,87,92,81,105,87,69,255,5,7,178,227,237,21,169,183,187,239,62,43,89,63,98,20,47,90,63,82,54,112,96,45,88,148,39,91,118,39,252,46,130,127,39,180,221,218,136,50,159,57,200,60,37,249,235,120,203,99,87,149,223,122,230,97,46,111,242,214,138,246,141,146,18,225,7,126,66,177,190,205,214,219,136,92,251,67,213,41,160,123,97,205,138,62,143,221,36,243,78,153,215,29,116,208,65,254,39,41,92,52,57,27,157,197,186,51,69,206,222,37,150,179,113,232,166,12,149,179,37,100,227,185,114,30,81,246,24,136,162,49,51,252,47,122,159,106,76,73,127,32,10,229,193,187,89,205,133,30,80,71,94,34,170,9,59,107,192,11,116,9,38,59,28,143,126,65,100,123,95,158,233,149,249,239,118,83,231,139,245,11,140,63,250,46,116,118,224,35,244,208,112,2,61,19,52,222,112,66,245,106,61,242,196,170,171,137,94,237,243,187,102,244,106,47,170,220,97,242,132,141,105,53,122,6,173,37,76,255,73,39,157,164,187,87,113,76,203,11,71,103,188,40,171,47,129,255,221,157,179,134,249,134,232,1,239,149,181,31,114,16,231,62,195,23,208,229,192,207,238,186,235,231,250,156,58,179,142,232,121,48,158,147,103,233,153,55,39,37,180,225,27,25,160,82,167,229,102,44,167,243,74,188,232,75,221,206,254,110,156,28,164,26,109,184,225,199,115,155,33,196,58,146,157,63,145,88,70,43,222,139,48,23,73,44,217,72,188,100,147,119,66,204,35,17,22,163,145,35,70,224,86,16,201,4,141,68,144,141,68,136,137,100,91,188,150,37,196,34,201,207,141,88,158,163,45,182,216,92,222,77,208,241,154,50,239,20,41,115,235,72,152,91,36,11,27,125,38,19,56,249,70,140,78,90,142,40,104,146,103,220,136,242,63,146,5,73,52,223,212,169,236,121,209,250,133,145,68,98,4,208,58,82,153,195,15,133,0,48,20,82,17,9,143,80,216,181,18,44,194,104,116,220,36,60,69,221,213,200,130,40,18,134,160,109,164,157,18,211,57,18,5,93,68,187,87,94,121,149,72,22,233,169,178,100,49,156,224,0,248,199,55,121,56,32,2,135,226,155,120,192,165,190,231,135,44,108,162,105,211,22,81,220,22,99,98,242,94,188,111,34,49,44,42,78,83,238,216,177,227,34,89,44,69,18,90,40,201,99,55,34,168,71,98,12,138,68,65,160,109,152,107,252,248,72,148,21,246,186,230,53,110,223,60,145,48,160,154,121,37,188,157,246,145,54,201,57,90,185,249,183,216,124,115,157,15,18,222,32,18,195,84,36,194,156,180,171,139,21,191,222,203,161,162,58,127,242,62,166,223,226,73,152,244,91,206,187,208,126,75,40,132,188,236,77,125,38,158,42,10,63,241,92,109,106,185,237,40,12,122,36,10,218,104,209,69,23,77,232,17,99,4,157,19,143,190,72,226,61,87,52,67,206,106,139,36,76,141,142,13,180,83,132,43,205,35,91,161,117,238,136,7,78,197,55,246,0,60,32,255,4,161,215,70,255,192,87,81,250,68,224,163,159,226,121,181,140,142,63,109,154,50,197,155,87,171,172,44,243,106,213,36,187,44,108,35,217,253,16,129,35,121,9,60,151,51,145,34,81,60,87,188,22,193,82,219,45,130,87,197,187,50,63,184,234,170,171,20,239,152,35,98,84,43,115,83,67,219,26,132,128,44,82,20,39,37,140,75,213,47,37,212,108,36,6,33,161,243,99,123,112,193,69,178,160,137,196,51,63,98,174,101,147,56,43,40,205,31,35,52,159,249,55,126,174,94,154,175,243,109,25,227,99,93,25,62,182,178,200,72,105,62,182,211,78,59,107,27,179,50,78,182,78,251,45,30,222,17,114,209,200,145,163,180,110,234,23,79,222,72,20,218,145,236,134,176,108,122,101,62,35,211,217,124,70,54,155,48,97,30,121,54,65,159,207,227,223,247,60,99,254,251,114,155,28,164,45,180,102,91,205,15,253,224,175,136,214,164,42,15,63,58,2,2,140,111,60,174,93,145,47,123,183,162,241,200,131,224,31,242,97,173,36,78,62,138,115,162,224,77,101,101,62,138,194,87,113,24,220,231,111,137,233,213,120,31,115,49,150,127,144,41,63,251,89,147,41,133,247,101,230,34,21,201,121,67,145,56,118,136,156,44,223,72,217,208,1,218,242,198,27,111,68,226,40,163,178,98,118,174,198,115,100,27,109,47,237,65,30,205,155,35,178,75,65,251,47,187,243,82,125,170,231,7,50,198,217,103,159,29,73,184,228,120,188,164,125,212,133,12,144,39,99,196,107,167,9,42,63,83,190,40,98,180,125,213,230,127,86,198,54,57,88,194,207,105,157,208,71,113,118,137,100,119,69,61,77,238,83,30,113,210,138,251,41,125,148,243,76,250,84,86,153,62,22,5,170,208,234,21,133,126,143,84,60,1,55,89,91,179,190,240,215,32,126,155,109,29,44,161,122,252,199,201,61,235,94,202,96,157,78,202,210,253,36,163,220,72,56,50,169,107,195,120,189,34,120,58,108,216,240,72,12,32,145,56,18,68,162,152,85,152,139,34,217,255,36,18,227,128,226,179,209,127,49,28,70,59,236,176,67,196,26,67,28,33,162,73,147,39,69,162,160,77,125,227,207,9,155,127,204,137,221,115,100,212,212,135,117,252,16,207,244,72,118,69,84,228,68,191,193,124,136,249,90,204,231,152,243,51,102,44,175,186,11,9,247,147,192,40,251,177,120,185,171,236,43,6,151,236,171,212,111,9,185,23,145,199,231,191,19,38,214,49,126,50,62,89,186,97,5,199,227,55,49,213,182,244,122,56,150,35,196,72,29,161,119,97,158,250,115,21,186,2,159,175,69,87,24,175,161,67,153,203,93,133,235,71,218,100,186,24,81,124,90,19,59,246,202,152,27,254,137,130,183,99,251,225,55,60,214,175,76,136,166,8,110,231,173,45,253,188,201,60,20,252,99,254,162,255,89,98,137,233,185,107,69,217,181,167,115,32,111,237,201,252,144,8,60,186,198,85,58,208,195,127,192,67,81,174,39,85,42,173,18,30,159,135,235,200,217,51,103,34,103,143,211,182,192,39,231,157,119,106,174,156,93,141,134,81,153,56,254,234,92,23,71,203,164,238,78,186,129,15,196,122,171,174,72,28,181,90,210,244,249,231,95,32,90,126,249,229,11,203,126,240,193,7,163,73,147,38,139,78,96,74,196,154,198,82,130,51,66,83,98,154,223,165,244,31,29,141,159,15,156,16,163,79,36,78,42,61,249,98,121,12,185,202,199,9,43,23,121,98,186,200,106,67,134,12,213,252,178,171,71,121,81,86,191,84,47,61,19,103,157,132,222,203,49,8,86,77,197,213,239,15,248,15,61,200,147,207,236,67,217,17,30,137,179,93,132,254,139,254,211,94,57,119,60,130,150,104,157,50,151,108,77,101,223,52,227,42,231,33,37,112,68,159,84,214,132,199,72,169,19,194,1,3,183,206,58,235,148,186,157,3,177,113,44,84,36,190,112,36,94,178,13,117,47,171,104,145,48,95,58,134,245,44,22,253,138,152,236,76,96,177,226,250,143,195,125,6,2,44,38,98,226,222,122,131,80,166,234,134,126,162,188,123,242,201,39,43,22,24,213,10,49,28,200,83,84,87,251,174,214,59,241,2,208,182,200,246,208,90,89,85,152,111,245,194,21,67,19,66,132,191,24,200,54,108,243,205,183,208,113,246,149,160,8,120,217,249,150,253,206,255,109,253,102,110,183,43,161,108,1,63,71,119,160,65,200,135,17,176,67,104,168,37,168,219,55,228,235,11,237,130,246,201,238,47,43,174,240,58,39,243,170,176,176,1,244,162,215,32,228,34,140,179,33,13,94,8,160,212,66,97,86,239,220,69,1,87,36,247,180,122,190,209,86,232,58,139,167,190,208,143,70,70,27,90,83,47,108,26,41,55,228,237,63,8,32,59,153,92,152,85,4,247,95,171,234,171,185,94,222,39,187,3,148,39,103,149,214,213,106,225,27,9,29,82,45,75,238,59,218,212,106,57,16,25,3,195,112,61,124,63,183,145,13,62,68,241,131,76,222,78,121,208,55,8,21,209,216,6,187,81,170,236,56,180,129,43,204,191,254,72,212,207,152,50,182,150,228,144,122,53,50,22,209,1,140,162,240,155,70,19,78,74,157,192,55,36,12,170,246,31,56,212,74,204,133,118,140,159,193,188,17,218,85,212,118,93,63,202,26,171,218,250,145,111,229,44,95,117,114,241,215,144,69,101,150,253,57,74,92,53,210,75,191,7,138,65,104,78,97,94,47,191,172,85,62,229,192,127,224,67,115,146,26,149,179,231,164,142,178,127,35,187,104,84,238,2,55,91,101,16,106,6,12,24,235,122,228,25,242,73,164,130,186,112,194,116,36,237,148,39,12,22,141,204,1,244,126,172,7,49,194,183,35,201,78,239,132,86,149,217,32,84,254,144,113,178,162,17,69,105,106,155,34,143,66,106,61,4,216,226,217,221,221,93,179,162,79,72,8,171,191,200,225,97,132,118,16,235,172,110,41,180,143,8,125,192,22,244,97,195,135,105,120,4,123,94,207,149,48,7,33,213,134,64,181,237,151,181,191,110,95,14,206,167,226,175,145,212,42,28,96,187,188,120,100,214,213,20,98,178,87,139,203,94,87,33,85,50,201,194,77,195,18,177,9,152,80,30,197,9,57,35,77,11,23,88,96,129,226,236,57,111,26,233,119,206,231,115,244,72,241,83,37,119,249,167,131,19,176,35,94,123,189,73,60,24,235,205,154,155,143,56,190,245,164,57,153,87,245,148,59,48,242,116,54,206,13,140,49,232,255,94,64,131,8,251,88,111,170,70,243,91,61,223,104,107,163,116,189,222,126,21,229,171,151,214,20,125,31,158,151,21,2,157,73,255,234,197,71,194,177,242,215,72,154,147,111,40,191,222,54,53,210,150,108,94,100,12,214,80,237,74,132,199,171,87,14,110,126,155,196,3,42,19,194,168,249,117,180,191,196,97,195,134,181,5,87,138,122,70,253,121,99,138,199,89,209,90,145,179,243,248,107,52,17,114,170,19,82,28,38,241,84,13,161,148,13,155,159,109,63,122,143,118,204,245,57,133,121,182,189,132,236,35,172,45,99,91,109,253,136,126,134,80,73,135,29,118,88,195,235,240,108,157,101,249,205,138,184,51,57,92,115,33,216,44,124,237,107,57,141,202,217,205,133,66,57,74,51,26,171,86,161,18,243,183,122,199,186,222,124,64,191,81,29,73,51,71,172,145,118,18,150,174,145,245,96,51,218,9,255,21,27,97,51,138,106,89,25,67,90,86,114,51,11,86,24,6,178,223,76,144,54,179,172,173,37,222,36,177,135,137,59,41,33,229,52,38,46,113,125,137,213,79,44,124,217,34,234,14,57,248,16,215,221,221,221,204,106,67,89,1,2,29,13,129,217,179,103,235,185,72,156,81,36,91,124,53,182,187,132,198,236,232,62,21,53,158,32,45,178,94,9,41,64,160,205,16,80,177,124,64,42,158,218,12,200,80,93,128,64,128,64,199,65,32,208,191,142,27,178,1,222,224,94,35,144,168,72,130,80,216,150,209,142,97,30,159,41,213,150,10,75,86,137,132,78,146,179,123,142,214,115,77,206,63,255,252,146,181,110,206,154,195,250,145,179,149,183,219,126,59,93,63,114,174,71,209,250,145,179,66,56,231,133,179,64,100,183,212,156,85,88,198,175,100,77,137,235,125,72,1,2,101,129,128,207,211,252,251,178,180,47,180,163,253,16,48,254,75,205,189,242,79,251,219,81,171,198,206,216,33,164,189,80,171,80,173,254,132,247,253,0,1,4,13,14,130,189,250,154,171,157,196,228,238,109,129,48,234,97,67,135,233,33,165,254,193,235,189,25,194,93,51,32,144,48,157,32,24,53,3,156,109,43,131,67,237,228,236,45,173,143,195,104,57,236,111,160,166,152,122,7,4,29,168,227,91,198,126,37,116,81,26,87,102,33,172,140,176,11,109,10,16,8,16,232,108,8,4,250,215,217,227,55,80,91,143,119,46,9,105,48,240,101,5,69,203,255,137,225,60,184,229,239,67,15,61,84,15,74,63,252,240,195,213,81,181,83,118,55,21,33,199,204,153,51,29,70,33,70,117,205,53,215,116,39,202,161,233,69,233,152,99,142,113,79,60,241,164,251,241,143,111,28,48,187,131,180,175,178,176,28,220,88,93,52,226,225,121,127,65,64,194,230,197,85,7,196,236,175,33,40,93,189,189,252,55,114,38,255,148,174,145,210,160,210,27,132,196,167,69,154,25,102,86,25,145,199,218,196,194,83,14,21,115,103,156,113,134,187,249,230,155,157,28,48,231,228,208,46,55,125,250,116,183,250,234,171,59,57,144,221,178,134,107,11,32,144,44,170,196,85,198,87,2,180,160,170,80,100,19,33,192,2,69,14,3,117,75,45,181,148,99,151,16,161,10,170,165,173,183,222,90,67,65,180,50,124,93,181,250,231,244,93,130,159,115,90,64,248,46,64,96,14,32,224,227,93,153,133,176,57,232,90,248,36,64,32,64,32,64,160,42,4,2,253,171,10,158,240,178,159,32,160,120,41,75,250,40,184,246,183,109,4,88,131,31,116,208,129,13,135,109,111,91,3,219,80,17,161,244,46,185,228,18,199,14,161,71,31,125,212,117,186,65,136,245,163,156,223,84,115,253,200,124,227,239,59,223,57,197,125,242,147,159,108,3,164,219,83,133,241,183,56,20,83,123,234,12,181,4,8,212,130,128,233,224,226,168,40,65,119,93,11,94,131,225,189,175,127,48,186,85,198,126,151,222,32,196,185,26,34,58,150,17,118,161,77,25,8,16,19,119,231,157,119,214,191,204,171,240,179,133,16,232,37,48,97,158,180,16,204,77,47,122,191,253,246,107,168,204,221,119,223,189,161,252,101,203,28,69,61,158,51,101,107,88,104,207,192,133,64,143,248,208,75,35,7,110,87,67,207,2,4,2,4,2,4,82,16,8,244,47,5,142,240,163,255,33,160,188,88,151,42,97,189,210,174,209,224,236,203,239,126,247,187,237,170,174,180,245,44,179,204,50,3,6,14,251,239,191,127,93,112,70,65,253,127,255,247,127,117,229,237,164,76,166,120,119,104,222,67,10,16,40,25,4,2,86,150,108,64,250,177,57,177,254,33,198,136,50,235,34,58,227,12,161,126,28,200,80,117,128,64,217,33,144,8,70,210,208,50,19,155,178,195,49,180,175,53,16,48,239,136,174,33,193,91,166,53,16,14,165,230,65,64,233,162,202,96,97,231,100,30,124,194,179,0,129,0,129,1,14,129,64,255,6,248,0,119,94,247,148,47,7,81,176,243,6,46,180,56,64,160,116,16,16,66,34,60,206,215,129,148,174,137,161,65,131,22,2,73,248,184,65,11,129,208,113,32,208,43,243,148,91,23,81,122,131,80,80,112,135,9,21,32,80,29,2,65,24,170,14,159,240,182,127,33,144,8,69,177,131,68,255,54,38,212,62,104,32,96,178,67,151,172,24,237,126,208,116,62,116,52,64,32,64,32,64,64,32,16,232,95,64,131,210,65,160,199,80,89,186,118,133,6,5,8,4,8,116,4,4,98,153,62,94,84,38,107,204,142,104,121,104,228,96,128,128,108,204,11,134,202,193,48,208,117,244,81,105,21,134,235,146,71,59,43,189,65,200,148,221,118,173,3,246,3,62,203,245,215,95,239,206,57,231,156,1,223,207,106,29,164,255,63,250,209,143,170,101,25,52,239,130,178,115,208,12,117,71,118,212,104,183,93,59,178,19,161,209,29,11,1,98,140,151,133,70,194,187,207,62,251,236,142,133,101,104,120,128,64,128,64,49,4,56,63,243,244,211,79,119,127,255,251,223,139,51,181,249,77,153,232,95,155,187,30,170,43,53,4,130,135,80,169,135,39,52,46,64,160,196,16,240,215,147,254,125,137,155,28,154,54,136,32,192,25,121,1,47,7,209,128,87,233,170,233,31,202,46,241,148,222,32,4,140,217,93,110,0,173,2,243,65,241,234,206,59,239,116,219,110,187,173,123,226,137,39,6,69,127,139,58,249,248,227,143,187,237,182,219,206,253,236,103,63,43,202,50,104,158,199,115,35,142,193,16,24,208,160,25,246,142,234,40,103,193,5,26,222,81,67,214,241,141,85,124,131,44,74,140,241,50,208,69,227,221,79,62,249,100,199,195,54,116,32,64,32,64,160,18,2,83,166,76,113,71,31,115,180,219,105,167,157,220,255,254,247,191,202,12,109,124,82,54,250,215,198,174,135,170,74,14,129,120,181,18,214,245,37,31,166,208,188,0,129,146,67,64,40,9,255,179,29,35,164,0,129,18,65,32,236,204,46,209,96,244,115,83,58,133,62,117,132,65,8,15,183,144,156,123,245,213,87,221,231,63,191,171,91,110,185,229,220,183,190,245,173,170,32,249,215,191,254,229,254,243,159,255,84,205,51,39,47,63,248,224,3,247,246,219,111,55,244,41,237,110,100,113,252,239,127,255,187,102,219,57,36,113,217,101,151,21,120,124,94,225,210,80,131,6,88,102,136,77,87,207,193,138,157,162,116,191,253,246,219,221,37,151,92,18,140,4,3,12,23,139,186,35,65,187,138,94,133,231,1,2,45,129,128,10,97,160,157,252,245,183,64,246,218,107,175,185,207,125,238,115,202,179,78,58,233,164,150,244,55,20,26,67,224,221,119,223,117,200,41,173,72,111,190,249,166,187,244,210,75,221,31,255,248,199,86,20,223,146,50,95,122,233,37,109,243,95,254,242,151,150,148,223,215,66,223,120,227,13,149,5,254,240,135,63,244,181,168,62,127,255,226,139,47,186,31,252,224,7,110,78,97,245,145,143,124,196,157,115,246,57,238,158,123,238,233,247,131,188,125,250,215,103,192,212,81,0,176,187,232,162,139,220,159,254,244,167,58,114,135,44,6,129,215,95,127,221,93,120,225,133,238,129,7,30,176,71,45,185,82,79,94,98,205,112,241,197,23,59,100,242,118,37,147,6,251,155,47,207,105,127,129,217,43,175,188,226,254,251,223,255,206,105,17,225,187,22,66,160,218,250,50,140,93,12,120,232,52,244,250,229,151,95,110,225,72,180,186,104,161,36,70,76,90,93,85,40,63,64,160,1,8,4,180,108,0,88,3,60,107,167,200,57,165,55,8,197,166,160,112,6,0,243,229,155,223,252,166,123,225,133,231,149,137,143,24,49,162,98,10,97,116,249,234,87,191,234,86,92,113,69,55,215,248,241,110,174,185,230,114,107,173,181,150,251,222,247,190,87,145,183,145,7,8,80,103,158,121,166,91,118,185,101,221,152,49,99,220,220,115,207,173,70,169,163,142,58,202,21,197,110,37,116,198,166,155,110,170,109,152,60,121,178,27,53,106,148,155,190,228,116,119,238,185,231,230,26,135,252,182,143,175,163,237,244,31,97,134,208,28,65,193,134,167,93,35,35,218,191,121,89,248,110,177,249,230,238,230,155,111,238,119,69,109,255,66,98,112,212,14,253,208,212,34,187,254,5,23,92,224,166,79,159,238,150,88,98,137,228,111,241,197,23,79,221,159,117,214,89,3,30,216,215,94,123,109,170,207,6,143,4,22,211,123,225,51,93,96,181,229,150,91,14,120,152,88,7,19,28,180,7,109,190,158,120,226,137,238,239,255,248,187,42,190,71,142,28,217,230,218,59,179,58,100,2,120,251,146,75,46,233,14,63,252,240,170,157,32,239,87,190,242,21,183,210,74,43,169,124,50,113,194,4,183,197,22,91,244,89,246,201,86,202,238,46,156,80,48,10,117,74,66,241,67,155,9,87,88,198,244,212,83,79,185,93,119,221,85,13,49,253,221,190,63,255,249,207,106,184,237,11,172,216,29,180,185,200,55,95,255,250,215,221,63,255,249,207,254,238,82,219,234,223,123,239,189,221,94,123,237,21,100,186,6,33,254,215,191,254,213,237,190,251,238,238,242,203,47,111,240,203,218,217,127,251,219,223,42,29,100,231,218,196,73,19,29,6,75,240,243,133,23,94,72,62,70,89,113,235,173,183,42,206,178,110,107,71,138,69,193,22,9,132,45,236,0,112,90,125,245,213,221,216,177,99,29,48,101,93,139,124,245,157,239,124,167,101,78,8,45,236,78,191,20,205,186,29,249,51,27,242,29,57,222,100,86,187,206,16,231,215,173,182,218,202,29,124,240,193,170,59,192,232,92,43,177,190,220,124,179,205,42,214,151,140,221,26,107,172,225,198,142,27,235,230,213,177,27,173,245,157,114,202,41,131,114,236,134,12,25,162,244,26,154,29,82,128,64,128,64,243,32,208,121,156,173,121,125,15,37,85,66,64,245,15,29,128,20,165,55,8,169,42,81,0,217,41,22,182,74,84,104,206,19,60,83,207,59,239,60,183,241,198,27,171,210,35,91,234,251,239,191,239,118,216,97,7,119,226,55,79,116,220,239,183,255,254,170,4,120,238,249,231,28,11,181,111,124,227,27,217,79,234,254,253,217,207,126,214,29,112,192,1,238,141,215,223,80,1,226,75,95,250,146,122,70,157,112,194,9,110,151,93,118,169,240,146,186,247,222,123,69,240,90,211,221,118,219,109,110,129,5,23,112,135,28,114,136,219,115,207,61,221,43,255,124,197,237,187,207,62,110,191,253,246,75,213,77,123,63,253,233,79,187,111,158,248,77,221,25,196,123,20,24,207,61,87,189,237,43,175,188,178,219,104,163,141,220,249,231,157,239,222,122,235,173,84,153,225,71,57,33,192,88,207,218,125,150,155,71,20,118,24,0,21,64,234,191,25,67,26,248,16,96,225,161,169,69,70,75,60,53,9,161,9,211,93,112,161,5,221,66,11,45,36,127,11,187,5,23,92,80,127,47,188,240,194,14,35,243,64,79,24,26,166,204,59,197,205,59,239,188,242,55,85,21,22,67,135,13,117,40,92,225,31,83,38,203,59,89,8,147,103,138,228,153,32,115,112,192,167,18,8,97,240,166,243,207,63,223,125,98,163,79,168,179,198,128,135,121,19,58,8,206,174,187,238,186,238,200,35,143,116,143,63,241,184,251,199,63,254,81,88,42,60,133,48,186,56,204,124,240,223,15,220,65,7,29,228,54,23,99,208,175,126,245,43,183,247,62,123,59,228,148,102,165,78,148,67,59,162,205,37,152,167,134,35,132,55,237,107,194,56,201,78,247,126,119,68,232,123,87,234,2,197,85,87,93,229,110,188,241,70,119,196,17,71,184,229,151,95,190,174,111,252,76,236,180,232,111,163,189,223,158,118,222,195,135,55,19,5,246,50,203,44,211,212,106,127,241,139,95,184,13,55,218,208,253,252,231,63,119,107,175,189,182,59,242,136,35,221,146,226,56,115,245,53,87,187,245,214,91,207,61,251,236,179,73,125,200,226,243,204,51,143,219,109,183,221,218,162,28,143,69,193,206,114,244,100,23,21,227,132,145,13,35,16,124,230,99,31,251,152,123,118,246,179,186,198,101,7,112,54,177,83,117,176,226,117,22,22,246,91,229,117,113,172,200,238,88,227,57,14,23,209,135,31,186,249,230,155,79,255,192,147,59,126,122,135,59,245,212,83,221,62,162,59,192,241,235,219,223,254,182,234,56,172,60,255,138,44,128,113,117,158,9,19,83,235,203,100,236,238,191,95,199,238,64,25,187,117,214,89,219,61,253,244,51,238,208,67,15,85,135,4,191,28,238,7,250,216,205,152,49,195,125,249,203,95,118,55,220,112,131,187,250,234,171,179,221,47,253,111,149,107,132,191,133,112,228,165,31,170,65,213,64,240,50,68,181,26,84,67,94,95,103,133,153,181,73,28,175,175,61,121,185,68,88,41,117,146,176,96,200,4,145,8,94,165,110,103,171,27,119,242,201,39,43,28,228,28,130,220,170,100,23,144,190,255,196,39,54,142,68,40,74,242,200,118,224,72,132,87,80,49,18,239,199,228,121,189,55,119,220,113,135,150,43,187,142,34,241,118,76,62,147,144,116,145,120,224,234,187,43,174,184,34,121,206,77,119,119,183,62,23,33,44,245,92,66,151,68,243,207,63,191,190,147,144,43,201,59,107,187,24,119,42,218,190,232,162,139,106,126,241,114,77,242,251,55,218,62,161,191,226,161,229,63,30,84,247,18,194,79,97,196,60,17,1,175,212,125,151,80,135,218,86,9,23,87,234,118,134,198,53,15,2,179,102,205,146,49,239,138,70,143,30,221,188,66,189,146,68,17,172,56,149,165,55,94,150,65,123,11,191,16,33,36,218,127,255,253,7,29,12,174,188,242,74,197,11,250,47,33,156,250,173,255,240,38,240,191,136,119,247,91,195,74,90,49,242,192,216,49,99,162,113,227,199,69,178,227,89,199,240,51,159,249,76,97,107,143,57,230,24,205,35,70,161,72,118,10,37,249,144,119,100,39,113,36,187,165,35,9,75,150,60,239,203,205,239,126,247,59,214,122,209,23,191,248,197,190,20,211,214,111,37,124,142,226,159,236,88,105,107,189,245,86,166,48,149,57,90,6,152,138,19,147,226,82,51,96,37,187,243,35,217,29,31,137,98,177,94,80,52,53,159,24,81,181,47,208,191,227,143,63,190,169,101,251,133,189,243,206,59,145,236,150,136,150,90,106,169,72,194,84,251,175,234,186,7,62,195,135,15,143,190,251,221,239,214,149,63,100,170,13,1,49,176,69,11,44,176,128,194,85,206,89,77,125,160,252,72,104,216,214,91,111,157,122,142,252,196,26,66,194,113,167,158,55,251,135,68,150,80,26,74,93,18,78,188,217,197,183,164,60,224,41,134,59,229,39,247,223,127,127,170,142,231,159,127,62,146,104,28,10,59,159,199,179,14,7,175,79,63,253,244,84,254,193,254,3,252,130,135,202,142,160,20,40,100,23,181,194,80,118,16,165,158,75,20,146,72,156,67,35,217,201,19,195,89,190,93,109,181,213,114,233,170,150,45,120,229,175,5,248,126,194,132,137,58,118,191,249,205,111,82,101,23,141,157,210,164,17,3,159,38,65,175,197,200,166,244,27,58,222,73,73,118,84,42,190,128,75,226,252,211,73,77,15,109,29,192,16,144,221,229,49,94,10,29,66,63,25,82,128,192,67,15,61,148,224,196,57,231,156,83,90,128,148,126,135,80,236,221,200,25,41,165,183,173,137,124,219,186,68,76,220,169,83,167,186,13,54,216,32,183,18,226,158,15,29,58,204,93,121,229,21,78,132,208,36,15,219,218,227,157,24,209,28,133,228,32,182,53,118,77,49,72,57,66,191,89,18,229,174,134,99,25,37,94,233,223,255,254,247,237,177,123,248,225,135,221,51,207,60,163,94,56,89,143,41,60,215,217,93,36,197,57,81,2,36,223,208,246,97,195,134,57,188,12,179,109,151,201,35,249,186,10,195,41,108,184,225,134,234,249,206,118,240,144,202,61,71,222,123,239,61,13,173,176,216,226,139,57,81,240,133,225,26,36,16,136,195,74,10,63,108,49,122,10,151,29,36,16,109,172,155,131,21,42,182,51,173,191,251,79,104,204,169,83,231,45,228,221,141,141,230,192,207,253,77,9,175,183,198,154,107,186,135,31,122,216,237,187,239,190,210,225,98,249,15,218,66,8,26,100,11,66,46,217,152,3,37,60,96,175,187,238,58,119,249,21,87,104,104,159,106,144,99,55,17,33,118,239,187,239,190,106,217,226,119,152,88,59,40,37,244,183,205,109,254,245,175,127,173,48,5,182,157,146,88,103,52,107,116,217,61,143,215,187,40,144,251,165,251,54,23,90,77,255,216,253,72,104,60,118,243,229,133,178,174,213,121,214,11,120,227,135,212,60,8,220,125,247,221,26,78,91,28,65,220,199,63,254,241,84,193,172,193,214,90,115,45,13,169,229,239,210,32,18,4,59,95,78,149,240,103,200,234,45,77,61,72,217,41,235,250,199,30,123,76,119,180,16,234,90,140,17,41,208,176,19,93,156,18,4,247,71,166,230,58,59,176,192,107,194,153,134,148,129,64,14,81,42,194,5,158,179,235,159,176,113,236,32,90,125,181,53,116,151,22,187,134,252,4,206,158,242,157,83,20,135,193,101,75,232,36,94,127,253,53,183,217,230,155,105,184,63,123,206,213,198,142,221,245,62,157,86,154,244,254,192,167,73,208,235,175,125,237,107,74,191,161,227,157,148,18,94,157,131,75,157,212,143,208,214,0,129,0,129,65,0,129,158,133,69,153,245,84,195,202,62,12,49,12,59,107,107,121,179,97,138,80,201,162,154,152,248,121,137,208,106,188,103,251,250,196,137,19,43,178,172,191,254,250,26,50,73,60,166,221,209,71,31,173,130,15,97,10,8,185,150,77,28,240,139,177,6,227,15,103,17,61,41,161,152,134,73,216,161,153,51,103,102,179,58,241,64,115,31,151,144,4,183,220,124,139,10,20,24,159,248,67,49,179,200,34,139,228,26,241,16,236,156,40,84,196,51,71,203,179,182,175,187,238,204,220,182,83,239,248,241,227,156,236,66,202,61,164,23,161,128,240,7,183,220,114,139,10,223,190,65,169,162,193,3,254,65,185,37,35,241,218,114,47,203,1,215,156,167,97,202,10,27,18,194,48,32,208,19,38,40,47,33,172,243,222,240,144,16,88,124,131,210,15,67,41,11,91,22,193,143,62,250,168,147,93,101,90,142,236,70,203,43,74,195,13,112,40,56,223,51,183,22,91,108,49,85,214,142,27,55,46,149,159,179,23,8,247,68,155,200,39,158,150,142,131,175,9,79,4,222,46,39,241,173,9,109,144,151,196,219,74,149,139,180,141,54,214,147,136,235,206,25,6,28,104,77,108,114,241,184,117,43,172,176,66,202,16,75,57,178,35,204,137,167,155,91,122,233,165,117,65,51,123,246,108,247,227,31,255,216,97,164,221,99,143,61,234,169,170,173,121,146,177,46,1,122,50,166,192,15,90,201,152,138,71,167,35,110,254,118,219,109,167,225,40,0,140,120,205,233,193,216,62,126,24,13,245,1,7,14,129,147,107,138,242,154,69,63,202,100,148,160,140,55,249,253,179,98,8,121,37,222,66,74,39,101,215,171,195,144,141,17,60,47,33,48,60,248,224,131,142,144,47,67,135,14,213,16,60,171,172,178,74,77,165,118,94,89,213,158,253,237,111,127,115,156,95,208,8,30,211,103,112,27,248,209,78,230,27,125,102,62,210,239,85,87,93,85,67,207,20,213,203,60,229,192,117,112,156,56,241,244,171,187,187,187,40,123,159,158,211,62,228,135,254,68,59,112,140,185,90,196,187,81,24,3,83,194,5,193,79,179,9,69,43,56,107,115,157,247,89,218,247,218,107,175,41,76,31,121,228,145,154,180,15,220,134,198,64,79,141,246,229,225,118,150,246,49,79,136,205,207,60,105,148,246,49,230,212,91,68,43,179,125,62,79,20,19,132,130,37,113,70,32,35,88,36,68,19,14,9,197,27,134,35,127,190,233,199,242,207,39,63,249,73,187,173,122,5,22,239,8,93,160,157,181,83,47,70,49,62,224,243,227,143,63,94,19,246,148,219,8,254,103,233,16,124,13,135,160,162,240,151,200,110,140,17,227,107,231,71,130,55,9,253,205,233,152,209,26,250,64,62,194,125,229,209,26,240,1,188,131,255,250,116,19,94,200,25,79,121,137,246,3,211,250,14,94,239,89,45,73,65,204,9,104,47,253,64,94,228,92,168,106,225,180,234,229,155,126,27,179,176,34,164,22,252,22,120,216,232,54,66,31,193,109,232,168,159,144,75,233,21,176,165,252,118,167,118,208,63,198,150,51,56,160,225,156,77,147,77,208,38,248,222,211,79,63,237,144,199,224,27,224,49,137,111,153,191,208,63,140,190,143,10,253,250,233,79,127,170,239,8,243,10,94,213,43,235,24,30,215,203,51,193,25,232,50,52,19,99,50,103,139,100,67,221,101,233,44,223,64,7,145,9,9,29,198,26,199,146,241,255,95,254,242,151,218,207,117,214,89,39,233,167,229,41,186,190,251,238,187,42,59,0,67,100,81,63,177,174,99,30,64,103,224,151,155,108,178,73,93,161,94,175,146,181,30,169,136,254,241,252,62,225,219,63,252,225,15,19,153,145,249,207,89,109,95,248,194,23,244,172,187,86,157,45,98,138,127,230,6,227,214,9,137,240,143,164,17,98,56,200,75,24,217,8,117,14,15,242,241,154,62,98,76,170,133,215,240,48,66,46,230,201,240,240,12,240,26,153,137,144,105,213,100,166,44,94,115,222,17,107,136,108,242,101,87,218,139,60,0,174,85,147,93,37,218,136,67,118,133,55,23,201,174,217,122,242,126,219,248,231,189,171,245,140,185,122,193,5,231,171,110,2,35,220,142,59,238,168,231,98,241,157,174,47,95,124,201,125,227,132,111,164,120,30,97,228,72,163,70,142,210,107,246,31,217,153,234,48,156,98,28,241,199,142,124,208,7,27,59,120,17,60,162,81,154,84,139,183,90,123,234,25,187,44,77,66,62,98,93,154,71,147,232,11,52,142,113,133,63,21,209,36,194,245,31,117,212,209,106,8,6,14,125,25,91,235,75,59,174,202,171,149,136,8,247,232,226,38,164,0,129,114,64,160,7,45,203,209,152,208,138,114,64,64,68,29,240,162,218,122,172,223,27,42,68,181,212,73,22,89,98,62,232,26,212,33,227,100,113,140,212,28,157,123,238,185,185,99,117,215,93,119,233,251,99,143,61,54,247,61,15,55,217,120,99,208,49,18,193,33,154,54,109,154,110,101,23,229,118,69,126,17,176,180,44,182,103,147,8,241,54,117,222,169,21,249,236,129,196,245,213,252,132,253,168,39,17,186,136,190,216,182,240,250,218,190,137,126,67,152,186,188,36,113,218,245,61,112,26,140,73,4,84,237,63,112,149,5,93,105,65,32,74,240,104,212,232,81,145,44,174,42,218,40,138,43,221,214,95,241,162,231,129,40,7,34,137,113,158,188,22,33,93,251,76,232,57,49,114,70,34,16,234,111,33,184,122,157,91,242,202,161,165,73,126,187,33,92,6,97,132,128,149,255,39,10,136,72,20,250,150,77,175,162,40,213,58,69,201,166,225,34,44,63,184,203,189,44,152,83,249,253,31,103,159,125,182,230,169,103,60,196,168,16,137,119,109,36,59,252,82,109,162,142,49,18,58,137,80,42,126,40,36,89,28,106,62,158,203,89,91,201,55,162,80,240,155,80,154,123,137,75,175,52,188,213,33,227,140,166,84,235,184,63,166,224,147,141,169,44,38,245,51,240,131,48,31,246,156,43,252,39,15,63,8,9,4,204,69,25,28,77,154,52,73,191,49,252,27,47,33,68,126,242,147,159,104,153,226,173,168,101,64,127,69,34,208,124,98,68,202,13,151,34,59,29,147,178,172,13,212,207,252,16,79,199,106,93,203,125,7,125,165,77,208,221,108,146,221,159,218,22,57,223,45,251,42,249,13,109,165,254,195,14,59,76,159,209,231,9,19,39,104,219,45,156,171,181,147,235,20,9,145,196,220,204,38,81,14,71,91,110,185,101,52,100,232,144,20,108,69,56,138,8,33,35,139,215,236,39,125,254,93,134,144,113,240,69,224,95,196,187,175,185,230,26,133,199,105,167,157,150,219,95,217,53,171,240,247,195,41,25,237,3,103,69,41,146,208,190,24,87,157,134,85,145,184,240,21,229,41,237,27,89,73,251,68,209,81,149,246,77,148,112,43,54,198,74,251,4,135,171,209,62,229,199,66,143,37,54,191,182,97,241,197,22,211,62,136,225,186,162,77,181,30,136,146,68,191,45,10,25,119,210,73,39,105,219,8,245,213,151,20,203,33,93,145,40,168,171,22,195,120,50,135,229,92,196,136,176,98,198,119,12,62,132,167,35,100,68,54,53,138,255,62,159,98,254,89,249,121,116,136,186,110,186,233,166,72,156,129,20,215,52,111,15,63,20,37,80,36,74,95,133,97,54,12,154,56,209,100,104,77,92,15,161,191,178,180,198,167,155,204,127,107,79,181,208,175,132,79,34,95,45,152,154,124,43,103,114,40,206,88,217,118,165,255,132,29,205,202,13,192,84,206,234,17,190,57,52,105,143,209,223,177,227,198,69,226,65,46,199,81,124,152,29,138,4,86,86,190,93,197,104,163,176,226,55,176,82,92,151,251,189,246,218,187,162,12,123,96,124,222,232,163,61,183,171,56,132,68,114,192,185,253,108,235,181,29,33,227,68,217,168,176,207,91,123,16,46,133,48,91,140,73,140,195,49,255,19,133,182,134,134,102,110,27,236,227,107,47,158,203,57,32,10,43,100,29,190,133,254,73,196,129,56,191,204,63,95,214,241,121,166,141,191,104,8,53,132,157,40,209,83,48,39,140,23,227,156,174,55,230,201,200,41,126,162,253,228,131,206,218,186,69,191,235,225,225,178,243,70,241,203,151,15,173,254,81,18,30,215,100,10,191,204,188,123,195,255,108,200,68,81,212,106,253,254,252,7,215,229,188,143,188,98,82,207,102,174,183,94,36,138,221,66,190,138,172,75,95,178,242,41,115,76,156,145,34,194,119,183,42,105,200,56,169,155,250,59,37,100,28,50,58,235,6,217,81,82,51,252,168,40,233,133,71,244,226,178,143,255,62,94,211,127,240,26,249,80,241,74,240,220,199,107,227,25,67,135,244,210,55,242,33,67,177,230,241,101,38,195,107,195,63,191,254,44,94,51,174,200,113,31,253,232,71,85,118,133,111,88,253,92,199,142,29,171,52,146,124,189,178,107,239,122,9,217,85,12,189,188,158,163,100,97,221,100,71,74,234,123,11,253,12,221,173,149,76,239,112,233,165,151,38,89,117,125,57,114,100,5,159,96,236,70,142,24,89,255,216,9,12,98,120,196,87,155,127,121,99,87,180,254,66,30,49,184,250,227,191,244,50,149,114,60,227,28,211,164,94,156,177,250,179,99,167,52,73,232,79,5,77,234,105,179,56,140,232,90,81,156,220,116,237,74,57,86,191,24,43,163,34,126,125,220,113,199,73,159,187,58,42,244,90,18,50,78,250,8,31,10,41,64,160,12,16,208,144,113,61,244,63,111,45,92,134,54,134,54,180,23,2,113,200,56,161,239,66,187,203,28,50,14,15,157,82,39,85,58,9,16,197,75,191,212,237,108,101,227,44,38,37,74,139,188,132,226,171,171,6,162,169,208,41,121,100,43,180,158,167,128,34,78,188,129,82,103,246,160,64,71,128,96,241,111,11,105,22,111,8,160,226,21,154,87,181,46,212,249,6,133,68,173,68,44,251,185,231,158,91,148,16,147,35,241,122,210,236,40,188,248,158,133,117,81,178,133,32,109,207,75,8,73,244,63,79,9,150,151,127,160,61,195,200,71,255,17,252,202,122,134,16,66,239,152,177,99,34,22,209,121,9,133,55,2,116,81,66,73,53,207,132,94,131,144,120,98,106,127,101,71,130,42,240,229,160,209,72,188,80,21,191,101,11,188,42,234,196,155,44,242,227,34,139,167,94,52,68,24,245,216,177,227,34,132,73,241,0,142,196,51,47,146,131,144,21,7,197,67,52,193,123,218,33,94,148,170,108,90,113,165,21,117,174,176,16,23,79,58,61,75,139,152,225,224,178,120,119,230,54,153,121,3,94,99,44,168,149,56,251,130,188,192,0,35,2,138,18,218,198,217,92,122,230,150,140,45,11,64,75,8,251,228,167,239,92,25,115,241,66,139,196,235,207,178,148,234,186,235,174,187,42,35,28,61,166,53,103,8,17,123,28,252,175,71,1,195,152,14,27,54,60,18,175,201,8,103,3,127,76,25,43,20,188,44,136,47,187,236,50,29,3,148,216,24,235,128,243,242,43,164,241,131,197,23,74,23,241,94,143,54,217,116,147,72,188,232,35,148,1,196,140,231,57,231,159,177,200,5,111,169,231,197,23,95,140,24,59,27,55,22,97,126,98,252,100,151,90,132,130,254,218,107,175,141,80,232,209,38,198,158,242,38,77,158,164,6,125,255,155,90,247,170,148,21,216,228,25,132,192,221,185,231,142,241,184,200,216,174,120,44,223,63,241,196,19,90,21,125,6,22,226,81,173,142,5,240,38,217,49,18,49,183,24,7,20,86,252,249,10,101,120,9,10,125,132,33,22,213,8,71,226,241,28,113,182,193,178,203,197,103,4,126,227,27,223,168,213,149,134,223,3,115,218,74,189,204,143,254,72,241,226,192,69,69,188,187,30,131,16,237,247,13,70,208,62,250,69,28,125,140,151,40,88,160,23,224,42,103,238,192,219,57,211,195,167,77,140,79,215,144,24,183,235,161,125,91,108,193,60,25,22,207,147,25,203,69,180,51,75,251,138,112,198,240,219,112,102,209,197,228,28,64,233,195,156,24,132,136,241,207,183,200,47,121,9,35,2,176,144,157,106,74,211,37,76,151,226,37,180,28,186,35,33,102,242,62,171,120,102,134,211,90,198,11,53,8,73,125,221,221,221,17,10,22,248,142,236,178,83,190,131,162,19,250,145,229,59,141,226,63,99,133,114,198,167,67,204,177,152,79,117,69,89,62,133,252,51,68,198,22,99,20,74,54,248,32,127,40,127,224,169,227,231,26,175,48,244,13,66,56,3,141,87,90,179,96,36,97,245,148,214,0,43,250,192,252,157,56,49,77,107,48,230,14,27,14,62,172,152,162,155,156,81,89,148,128,37,99,83,132,251,246,157,193,116,156,208,93,242,139,183,189,210,73,202,230,91,248,47,207,179,56,96,124,19,217,192,248,38,253,70,30,86,190,41,223,208,31,63,177,64,239,234,26,162,116,22,88,49,111,12,86,24,245,237,44,16,206,220,97,254,200,110,172,104,238,121,230,174,80,50,90,153,178,203,94,219,86,196,231,81,244,205,88,126,134,101,111,235,149,51,59,129,27,243,167,85,103,8,129,83,212,113,239,189,247,86,244,237,35,31,249,136,206,7,9,41,29,201,174,47,149,181,226,249,218,21,65,239,81,104,243,157,25,8,100,135,133,254,230,217,83,79,61,165,229,97,108,161,253,208,58,232,23,115,0,90,110,206,108,240,83,230,201,66,11,45,168,198,60,120,166,143,199,140,169,120,213,39,109,179,57,180,195,14,59,104,93,240,33,240,148,115,86,145,159,49,158,90,162,30,250,182,210,202,43,41,190,208,15,248,59,117,107,123,228,29,103,98,162,88,255,244,78,159,142,48,62,33,187,65,171,161,157,200,135,126,221,86,110,246,106,248,15,222,91,178,103,240,91,232,46,134,26,224,50,101,202,188,74,95,106,41,228,113,160,194,24,89,148,160,89,244,23,26,153,77,200,232,163,71,143,153,163,243,160,178,101,229,253,182,241,166,254,78,49,8,209,143,79,125,234,83,130,15,93,58,246,178,107,43,175,107,250,12,231,45,198,10,185,13,252,145,221,171,9,94,3,119,18,120,75,255,87,93,109,85,157,35,224,37,223,24,94,39,60,67,242,32,51,33,79,37,50,83,207,185,202,190,204,196,247,148,7,94,35,31,144,87,34,38,196,231,7,203,252,241,241,154,250,193,171,17,34,59,32,127,201,174,51,93,59,48,119,12,119,23,89,36,150,93,49,232,34,71,65,75,98,217,117,53,237,83,86,118,165,204,122,147,25,132,178,103,8,153,115,71,61,6,33,100,125,250,75,191,73,172,47,225,31,69,235,75,29,187,30,58,82,109,236,140,38,177,134,244,199,14,152,250,99,199,59,147,115,178,235,47,95,142,135,183,66,51,144,133,192,251,97,194,91,209,127,176,102,183,20,211,36,23,225,140,11,14,64,43,225,123,241,217,207,233,177,51,154,196,153,206,208,61,96,8,205,1,111,214,88,125,117,109,51,50,9,242,137,236,216,84,188,65,134,194,240,8,255,46,162,73,212,11,60,79,56,225,4,107,86,233,175,193,32,84,250,33,26,148,13,68,15,9,125,224,15,217,60,164,0,1,53,8,9,255,129,198,6,131,80,31,240,1,165,29,19,75,66,13,244,161,148,206,254,20,166,15,12,138,4,25,20,144,8,170,44,132,139,210,129,7,30,168,101,216,46,26,132,24,202,52,69,51,66,8,138,12,20,132,190,226,6,161,130,124,121,6,31,140,68,75,202,129,132,188,103,177,148,77,236,92,57,227,140,51,84,161,186,233,166,155,170,162,97,94,81,84,33,124,88,226,61,223,99,24,42,74,217,182,103,243,33,128,209,255,172,128,153,205,55,80,127,199,59,132,98,239,162,178,26,132,108,129,235,43,165,252,241,64,169,206,226,163,40,101,119,8,169,87,101,15,129,205,91,64,160,192,194,179,11,129,220,18,11,127,60,31,57,180,60,155,48,56,131,135,190,71,169,132,71,18,101,68,151,46,172,179,11,215,189,247,222,91,21,21,24,109,178,9,226,15,225,159,57,115,189,236,171,138,223,230,69,141,129,34,79,193,202,34,13,37,21,187,107,80,10,146,88,28,210,86,20,37,44,162,202,158,240,114,163,189,236,118,106,69,138,61,11,187,162,173,182,218,74,23,52,44,106,252,63,12,21,150,108,76,231,155,127,190,10,101,4,139,176,13,55,218,48,23,63,224,63,244,65,66,72,88,81,209,166,155,109,170,227,44,33,141,82,222,154,100,240,61,43,241,114,246,19,202,67,198,14,156,247,19,56,62,108,216,80,53,174,248,207,185,71,209,79,253,141,42,246,12,191,242,12,66,148,187,207,62,251,106,185,69,120,12,254,207,156,57,147,172,154,36,84,142,230,151,16,20,185,94,162,114,94,157,190,71,49,97,201,140,254,24,246,179,137,121,197,34,21,197,117,61,202,179,236,247,213,126,91,189,192,173,191,12,66,181,120,55,134,63,218,87,116,240,180,245,193,223,33,100,30,229,224,80,158,17,52,166,125,46,69,251,192,237,79,124,226,19,117,227,182,206,19,105,215,212,249,166,86,204,19,165,125,242,142,5,121,54,197,158,80,208,190,153,201,43,232,22,10,94,115,50,73,94,212,113,99,187,8,138,118,8,237,188,243,206,10,63,240,27,99,12,242,34,121,37,84,142,210,127,148,38,56,162,212,74,240,6,198,1,56,85,75,198,199,200,235,123,39,219,55,192,158,119,62,223,177,49,172,23,255,105,67,45,62,229,211,161,216,249,32,223,187,23,126,134,129,135,54,249,202,158,165,150,94,74,149,214,121,134,140,60,90,99,248,192,188,207,242,66,235,123,246,74,63,168,23,216,86,75,62,76,125,90,109,223,96,152,65,193,69,63,48,150,145,48,38,131,255,43,86,229,155,115,167,248,38,223,197,6,238,174,72,194,92,242,51,149,98,88,197,59,24,77,78,169,133,235,49,159,159,153,42,199,255,129,34,18,3,127,127,36,28,16,128,63,127,141,242,141,122,219,43,161,48,21,198,236,80,240,19,74,80,228,47,159,14,240,158,124,40,64,207,59,239,188,36,187,205,15,159,198,217,203,68,214,145,62,192,231,179,105,105,49,6,98,124,49,188,240,223,231,225,49,59,27,55,16,131,135,239,40,196,55,134,171,59,236,216,203,183,48,196,216,78,139,236,110,115,140,78,24,168,24,127,148,235,217,4,93,162,255,208,247,90,201,240,223,223,33,68,59,243,230,14,59,15,80,86,251,243,63,175,124,248,233,244,233,75,230,189,210,103,56,228,81,254,230,155,111,81,145,199,140,124,182,86,172,200,208,199,7,106,16,146,185,75,253,181,12,91,125,172,170,169,159,163,196,55,71,47,218,190,202,170,171,232,46,68,112,61,47,85,195,107,104,13,101,176,110,205,195,107,251,54,107,4,167,30,214,234,200,76,236,212,52,195,130,226,181,224,33,107,65,63,153,252,231,203,99,188,55,57,110,229,149,87,201,149,93,227,182,185,40,87,118,149,118,103,101,87,191,206,90,247,106,16,146,241,207,174,215,129,3,142,93,121,235,185,108,153,186,51,81,242,110,179,205,54,250,202,230,144,209,237,108,126,27,59,230,43,115,26,99,14,187,112,89,95,229,37,131,127,85,154,36,245,231,173,191,144,227,135,87,163,73,82,191,223,78,198,14,67,86,238,216,73,94,127,236,148,38,41,222,184,138,8,24,74,147,36,63,99,151,71,147,112,150,161,255,121,52,9,93,14,107,76,214,52,157,146,144,63,117,60,165,79,97,135,80,167,140,218,192,111,39,78,128,224,37,252,63,24,132,6,254,120,215,211,67,91,23,131,23,101,54,8,13,17,230,81,242,36,32,28,228,73,4,64,133,0,231,250,228,37,226,161,11,158,21,198,150,231,27,226,227,146,100,33,164,87,241,240,209,152,231,178,0,215,115,81,136,127,76,140,224,51,207,60,43,137,201,75,70,17,86,52,191,132,22,112,178,192,212,123,254,17,229,142,30,34,251,152,196,206,39,17,67,59,155,200,127,192,1,7,184,147,190,249,77,119,235,109,183,178,27,205,29,254,229,47,167,14,229,36,62,178,8,129,13,181,61,91,143,120,1,202,163,72,99,207,103,223,13,158,223,200,129,178,188,0,152,37,76,226,97,166,173,18,197,78,110,235,192,141,106,41,251,94,251,41,159,116,79,155,230,68,209,86,241,169,44,20,132,35,71,78,140,155,201,59,98,250,11,131,118,18,34,43,121,102,55,118,118,145,40,47,237,145,158,223,194,146,141,57,32,11,236,228,57,55,196,89,231,157,132,221,74,61,231,135,40,105,121,37,121,106,159,231,35,198,41,197,127,230,35,241,195,179,137,216,207,162,236,116,226,33,170,241,222,121,175,49,72,153,51,227,198,247,28,186,158,253,170,92,191,101,87,150,32,102,76,51,90,215,178,200,137,103,142,30,144,202,33,169,250,119,84,124,253,234,87,190,146,208,39,81,42,202,184,69,110,207,47,236,89,49,166,178,51,210,253,244,142,159,230,226,135,40,182,180,233,196,122,183,52,164,107,136,142,51,180,81,203,181,23,114,21,3,184,226,159,44,60,43,206,197,226,44,128,238,143,118,235,89,44,246,9,52,92,148,90,110,235,173,183,73,206,50,178,119,92,137,81,79,186,249,166,155,244,218,200,63,2,122,165,189,121,223,236,177,199,238,138,127,69,120,76,7,21,215,123,62,102,44,41,143,246,136,1,183,162,72,206,176,130,79,49,22,198,19,100,17,171,227,47,198,234,138,252,204,43,230,47,103,77,200,162,174,226,125,95,30,24,205,168,214,255,190,148,95,207,183,162,60,87,120,197,60,170,242,11,218,200,244,176,182,86,230,136,159,84,188,151,111,166,117,79,115,162,48,170,248,68,105,159,60,149,29,181,201,59,112,91,12,35,117,227,182,40,89,245,219,189,247,218,187,98,158,232,57,101,82,191,40,110,146,242,237,70,118,165,232,173,79,99,137,189,207,185,33,173,224,77,38,147,72,152,58,39,187,250,244,236,173,31,252,224,7,26,59,255,226,75,46,118,98,100,119,251,238,179,79,234,144,116,226,234,131,187,252,129,127,147,38,77,116,155,203,97,225,36,206,122,138,159,77,210,171,236,148,209,178,244,101,207,63,210,117,183,216,226,139,57,49,60,249,143,245,158,51,117,72,62,223,105,20,255,25,171,106,124,138,250,141,14,201,66,67,207,13,90,111,189,153,78,194,0,105,221,254,63,178,235,212,237,176,253,246,41,250,11,173,121,244,145,71,157,24,208,245,92,18,63,63,247,28,222,77,18,39,32,189,242,143,209,183,60,94,200,123,131,41,120,14,252,248,219,124,139,24,166,159,20,152,138,242,50,121,206,59,242,103,19,223,202,14,146,236,99,39,142,4,78,156,130,148,158,112,230,9,233,188,243,207,147,73,227,220,177,85,249,230,126,202,55,69,153,175,223,24,172,214,23,57,128,115,223,178,9,88,109,183,157,192,74,146,225,170,209,190,34,250,40,77,200,157,83,90,136,252,67,159,94,23,218,214,31,201,104,6,248,98,247,205,110,7,114,29,103,159,101,207,238,84,89,70,86,151,162,136,213,115,57,172,94,242,137,226,55,197,83,236,93,222,213,240,142,243,29,89,163,248,9,60,126,68,206,176,219,122,235,173,171,242,204,91,110,190,57,249,76,66,119,186,59,229,204,13,49,20,39,207,184,225,124,13,228,170,103,103,123,252,93,126,131,99,162,224,213,58,252,15,56,235,103,241,197,22,87,254,47,225,35,253,87,122,191,241,198,27,43,255,183,179,82,43,50,212,120,96,237,179,181,159,101,167,92,81,38,235,89,38,246,44,239,10,108,198,207,149,62,19,211,207,103,229,191,253,246,91,254,99,189,183,179,145,76,102,175,200,208,140,7,76,28,73,173,194,203,184,244,230,254,203,217,109,156,19,41,59,11,221,26,107,174,225,30,248,221,3,42,7,193,223,192,193,236,88,91,223,140,150,248,173,177,103,227,229,124,220,44,94,147,79,121,134,92,197,120,234,127,166,247,208,20,100,166,215,95,123,221,201,206,21,125,166,120,45,231,91,101,207,65,229,204,46,217,149,226,102,63,59,187,162,28,30,28,118,216,161,9,109,183,12,200,174,164,34,217,117,90,119,183,123,254,133,231,45,251,156,93,101,252,13,62,126,1,53,150,129,73,86,120,8,147,207,230,7,186,11,210,180,105,211,146,60,254,77,50,118,23,92,224,100,39,141,158,147,12,159,147,16,128,110,235,109,182,118,226,120,226,103,79,232,127,234,97,207,143,106,235,47,206,248,65,142,223,170,128,38,41,111,149,78,114,230,171,37,198,142,115,128,242,198,142,53,134,47,75,80,55,244,92,28,58,114,105,18,107,11,82,30,77,226,236,39,166,93,22,79,201,143,188,7,30,191,252,82,12,71,158,117,66,234,33,35,157,208,212,208,198,65,4,1,240,18,253,83,72,1,2,64,192,120,93,217,49,34,94,245,151,122,204,98,133,73,169,155,216,226,198,153,114,6,35,76,94,146,179,48,244,177,120,82,230,189,214,103,178,165,90,5,9,91,8,112,248,165,120,88,168,208,183,225,134,31,151,195,142,223,208,3,163,179,74,14,20,161,18,39,87,15,25,93,113,197,149,228,144,210,45,84,112,145,237,232,142,5,182,120,64,234,97,152,42,160,101,106,239,22,193,17,37,31,66,18,202,169,203,68,81,115,168,8,160,212,43,30,121,122,248,184,181,157,133,99,81,18,175,66,125,149,21,152,44,191,41,30,13,78,246,124,48,94,141,240,148,173,239,40,124,17,100,89,204,228,165,90,237,102,1,37,161,94,42,62,229,192,84,21,208,51,111,244,128,118,161,190,121,139,90,9,11,160,138,67,4,109,12,64,204,27,14,227,38,217,2,67,127,208,96,17,161,205,24,160,207,122,254,225,160,107,234,6,143,81,206,73,120,20,125,67,217,40,38,153,15,226,85,237,127,146,123,47,94,93,250,92,60,186,114,223,243,112,189,245,214,115,24,110,37,100,129,230,209,197,164,244,141,3,96,139,14,24,47,44,172,31,94,124,200,42,79,254,87,195,80,11,235,23,143,63,199,1,169,150,128,19,120,5,126,152,98,41,126,215,85,97,164,177,111,184,102,241,3,165,178,132,203,144,55,93,41,252,48,156,205,30,70,77,25,18,174,69,251,44,59,22,248,89,145,48,244,205,22,154,40,158,121,170,76,147,144,15,154,7,186,156,53,140,88,63,198,137,1,240,105,79,201,95,81,104,193,3,220,149,20,103,114,222,131,199,18,126,66,15,203,174,192,227,203,193,227,9,41,60,150,97,212,69,37,56,153,151,104,63,101,162,208,54,101,225,239,255,32,176,147,15,153,91,217,190,105,25,58,207,210,6,140,188,178,27,125,102,116,161,90,255,27,45,179,209,252,180,129,250,139,120,183,149,103,184,100,191,253,171,160,113,106,252,108,254,131,119,214,71,63,191,210,62,121,32,97,99,252,199,122,159,197,109,104,223,31,24,31,73,62,237,211,246,72,189,40,148,178,73,194,100,185,21,87,168,196,25,248,48,60,30,218,135,81,170,89,137,254,23,37,155,215,56,158,136,87,126,42,27,74,51,140,26,215,94,119,173,30,12,109,7,172,115,48,117,74,206,145,242,159,121,250,25,205,43,231,16,36,180,220,10,99,174,250,137,57,176,252,140,229,83,99,98,239,37,84,153,222,250,124,103,78,241,223,198,138,121,201,159,209,33,234,183,177,50,158,144,199,163,172,77,107,173,189,182,187,242,170,171,146,246,202,142,106,125,37,103,133,36,243,145,241,246,105,4,114,226,51,179,159,177,34,122,174,93,185,248,192,203,10,152,202,51,218,140,226,75,118,100,84,192,84,233,99,79,169,118,145,48,92,106,252,177,223,254,53,54,224,116,169,28,201,243,39,159,136,249,166,120,86,251,217,82,247,198,55,141,199,42,172,100,172,205,249,35,149,185,231,7,134,129,107,174,190,58,89,192,65,203,86,94,121,37,39,187,156,84,86,144,51,156,52,39,99,131,225,177,22,174,171,108,58,164,10,2,231,53,162,73,207,140,54,180,146,254,97,240,206,115,84,67,174,95,247,99,235,58,217,97,224,214,90,123,45,183,215,158,123,169,209,53,59,151,234,233,42,243,31,89,43,43,235,100,121,166,241,73,43,147,223,224,241,223,158,121,218,30,37,87,217,25,160,7,198,75,200,64,89,251,188,238,88,31,225,52,103,243,42,201,40,140,107,133,21,87,232,253,233,221,129,243,18,10,74,29,235,188,199,122,107,252,63,143,6,103,243,230,253,198,64,125,234,119,79,85,197,63,70,8,12,14,24,124,109,76,243,190,241,159,1,255,119,223,41,94,15,202,110,132,212,122,208,255,214,100,116,100,246,86,166,254,153,21,125,235,17,107,76,28,34,248,99,253,128,129,90,162,92,168,3,12,70,110,217,121,152,24,37,108,172,242,120,59,184,73,255,225,225,89,188,166,133,42,111,74,6,240,145,50,141,62,103,203,98,93,237,39,31,175,49,10,130,215,195,70,12,119,175,190,242,170,159,77,105,189,213,159,122,33,63,140,54,23,201,174,83,133,31,34,135,178,46,55,71,211,108,25,245,252,246,249,77,61,249,253,60,102,192,49,253,1,116,136,4,61,46,74,140,157,132,223,211,63,120,147,236,226,213,177,187,81,156,151,126,253,171,95,171,147,130,25,148,20,206,5,8,170,237,22,38,156,183,254,242,105,146,141,91,182,61,99,199,142,75,25,121,236,189,63,118,208,164,24,190,195,133,62,165,231,33,252,127,198,114,51,236,179,212,21,154,36,187,126,115,105,146,210,94,233,83,17,77,98,222,251,114,75,170,224,18,254,200,206,133,18,54,49,52,105,48,67,128,137,26,82,128,128,64,192,248,61,178,120,153,83,7,24,132,68,151,52,200,39,150,9,57,120,193,224,197,145,77,114,94,128,62,170,38,192,35,96,128,140,38,236,241,1,2,31,158,151,18,115,86,21,166,114,142,79,182,104,253,205,142,7,22,100,151,200,21,175,219,41,147,231,117,27,108,176,190,126,135,135,210,141,55,222,168,10,129,236,199,8,96,190,215,170,28,4,169,222,167,114,216,175,147,176,1,42,140,33,192,48,190,180,175,40,153,176,71,222,188,100,2,142,45,100,242,242,12,228,103,157,32,24,177,195,5,252,147,80,7,185,67,81,207,226,32,138,254,87,241,173,41,104,178,47,80,4,176,228,202,194,230,148,83,78,113,18,39,219,61,255,28,30,110,162,4,251,255,246,206,3,80,138,234,234,227,247,65,44,136,8,8,98,137,5,20,17,98,44,177,32,246,250,89,34,177,99,212,88,16,21,177,27,197,138,5,123,137,5,75,98,236,93,49,159,177,97,139,230,179,128,221,168,88,81,99,141,138,96,139,5,212,68,101,190,243,63,243,206,188,187,179,51,251,246,149,221,157,217,253,95,125,204,236,148,91,126,247,204,185,253,92,233,176,69,163,2,157,109,113,23,204,9,21,143,117,242,197,239,99,246,240,1,7,30,224,240,125,136,233,69,189,45,27,117,107,165,26,223,21,58,199,91,115,98,74,73,26,49,125,138,102,135,249,239,217,55,139,70,12,156,21,46,152,221,150,43,87,161,142,49,203,99,232,201,180,188,50,78,225,179,129,206,106,182,107,254,17,131,74,19,206,159,224,62,248,48,92,41,134,70,189,201,71,104,141,161,229,4,252,195,216,0,0,64,0,73,68,65,84,105,149,217,152,78,181,187,152,213,14,249,75,234,44,195,51,221,231,11,103,40,91,220,197,52,142,190,138,193,196,27,111,184,81,36,179,184,208,67,199,216,172,217,223,68,131,72,22,86,171,199,98,175,10,94,217,107,175,189,117,150,42,86,119,64,47,195,221,35,179,170,103,206,152,169,51,246,139,229,184,201,165,125,119,120,215,244,180,152,82,81,206,47,191,244,50,46,187,245,101,21,131,37,43,236,14,41,76,165,191,58,79,95,232,224,63,198,22,97,150,163,95,58,24,92,226,235,90,38,73,248,40,195,210,152,161,252,43,21,191,120,253,199,190,255,52,255,108,226,68,124,16,10,229,46,244,31,58,83,192,95,246,157,113,61,211,116,31,2,149,255,109,112,41,158,56,116,136,97,102,179,152,77,211,213,120,184,15,221,55,227,19,145,153,131,15,113,24,108,232,44,23,79,191,239,175,197,15,171,106,146,28,6,129,196,68,138,118,220,218,125,204,128,71,39,158,239,208,225,143,193,35,172,124,195,64,66,105,215,164,51,139,147,158,73,98,223,30,249,71,62,33,191,172,227,43,212,67,61,165,156,250,78,130,21,69,208,236,108,182,175,125,115,118,221,63,90,157,209,100,12,19,121,144,255,55,138,174,129,190,137,59,220,195,151,137,193,66,191,211,15,250,207,120,199,223,73,99,138,1,161,242,152,186,196,186,173,133,131,244,33,124,116,154,193,189,45,229,38,190,45,155,224,100,207,249,71,43,55,141,145,30,69,166,237,186,255,172,157,135,172,10,235,13,163,70,237,165,178,142,21,113,126,57,143,250,184,152,249,42,41,235,232,208,237,35,229,123,45,92,53,244,31,234,117,105,117,58,116,150,163,3,22,101,9,244,133,236,69,234,134,174,62,84,219,28,98,138,186,108,36,248,254,147,228,78,203,76,249,20,32,195,145,28,227,211,144,231,225,124,57,182,137,23,24,28,196,44,253,251,238,189,79,6,233,127,210,71,81,86,67,142,100,243,249,240,197,230,127,141,223,194,253,100,114,71,130,211,111,93,194,75,106,119,96,133,148,134,95,74,121,37,248,105,151,48,65,232,170,43,175,114,88,125,140,58,9,254,250,246,237,227,70,140,216,209,137,41,188,84,253,99,239,163,77,248,197,231,133,29,201,118,15,71,107,43,38,13,208,89,39,187,89,147,240,223,235,140,243,176,252,242,50,170,51,60,173,129,31,178,119,148,202,18,86,240,99,50,2,228,29,250,1,3,197,112,38,63,165,162,150,36,215,120,254,165,151,94,82,57,246,7,250,81,255,83,209,150,134,20,52,52,156,233,54,200,53,86,133,220,115,239,61,110,206,79,225,196,81,212,49,101,223,86,247,253,119,133,114,141,247,64,31,46,41,255,77,167,38,201,53,222,193,128,134,189,143,223,112,144,73,49,5,39,177,146,120,225,127,145,251,112,5,125,224,176,50,92,246,59,10,31,148,127,91,242,63,186,212,230,19,27,228,183,54,144,77,134,53,217,109,205,67,76,224,131,30,192,68,18,232,162,196,188,11,17,23,121,101,245,47,11,219,127,0,101,43,92,98,61,222,19,249,111,189,178,21,109,64,148,145,168,63,161,206,134,220,157,183,219,188,145,78,154,211,220,14,109,9,167,41,49,223,112,191,84,222,233,189,148,52,225,93,176,195,0,121,94,156,214,103,154,153,150,243,173,229,37,93,140,103,125,16,192,119,76,71,2,32,0,93,165,131,65,37,244,111,22,72,229,98,64,40,252,172,26,247,227,10,59,21,11,103,167,251,194,99,51,63,172,177,236,223,179,115,116,206,193,249,21,64,84,162,96,218,7,122,107,142,204,238,69,231,78,210,82,99,188,135,134,47,254,48,51,210,95,137,35,123,79,224,118,171,29,177,250,144,252,131,138,161,236,151,160,230,107,112,77,27,231,18,126,169,153,41,51,180,19,32,189,18,132,70,55,210,96,3,103,22,86,163,28,253,138,81,86,211,108,157,202,86,113,47,138,167,52,32,74,85,234,190,211,70,77,139,14,176,74,185,205,194,139,251,135,235,241,37,187,88,101,51,110,220,113,110,217,101,7,186,43,175,186,210,97,54,56,6,16,32,207,98,215,179,200,252,154,114,21,143,173,146,29,15,67,108,50,187,177,99,143,208,213,115,232,72,199,243,24,28,130,48,154,169,197,248,59,241,223,232,84,248,234,235,175,226,151,11,126,163,51,3,126,90,39,43,56,161,112,73,139,87,193,203,25,248,129,62,17,228,92,188,131,186,179,162,102,242,95,142,255,38,47,73,236,96,202,230,88,49,47,7,179,11,232,252,131,124,64,95,66,62,96,214,1,3,218,69,78,50,194,252,244,239,37,201,159,127,31,13,103,173,32,52,95,180,248,160,147,125,228,200,145,122,53,233,123,128,191,190,254,245,253,76,63,111,249,110,146,158,81,57,150,206,4,200,46,76,237,129,39,202,2,100,154,153,76,42,124,47,208,142,226,194,107,45,191,66,121,117,145,9,196,249,164,99,98,182,152,42,157,34,147,7,236,155,194,211,72,159,255,59,169,129,221,226,107,59,207,144,116,1,157,196,178,157,62,182,233,53,43,187,205,164,73,226,203,18,199,52,217,69,135,107,60,247,236,251,183,213,49,137,126,198,46,170,108,143,59,86,205,28,193,252,21,204,135,160,236,133,9,39,200,54,204,170,249,78,101,90,2,54,185,244,239,225,28,43,108,142,24,59,86,190,147,107,180,51,8,249,8,127,97,37,33,89,102,226,62,148,255,59,158,126,255,77,235,220,79,50,95,136,231,140,191,77,42,241,223,109,255,121,16,91,113,24,247,169,80,39,180,85,254,101,95,2,53,199,43,155,74,43,83,228,85,92,15,217,119,99,186,39,77,126,16,51,76,118,0,67,123,6,121,10,253,35,155,157,71,186,198,79,129,249,141,163,111,10,12,122,60,77,30,252,247,11,206,37,224,114,190,61,196,207,86,130,23,188,223,252,3,247,16,190,213,35,230,95,160,135,251,74,86,181,151,114,170,135,196,227,185,231,14,39,102,132,233,106,138,76,89,38,189,139,239,77,98,92,160,211,147,202,121,12,158,35,206,24,232,40,229,62,253,236,83,25,48,232,91,234,145,202,222,67,36,43,168,255,230,153,103,94,29,56,76,74,4,58,148,209,190,128,89,71,177,171,175,3,174,48,91,137,206,115,116,130,218,228,3,188,139,104,166,57,220,75,146,59,189,38,105,59,224,128,253,213,138,129,95,158,32,175,77,238,112,142,50,19,3,62,178,113,187,195,10,57,212,207,100,111,67,53,189,38,123,52,106,208,126,219,8,23,66,121,105,57,234,67,241,127,36,124,123,206,191,213,90,249,239,63,139,243,164,244,163,30,128,206,106,217,255,78,219,75,127,249,203,95,180,158,138,142,99,172,180,45,85,94,162,94,251,246,59,111,167,78,30,65,91,81,162,158,56,56,106,117,116,171,111,198,227,218,209,223,90,126,201,55,150,152,232,142,122,94,131,247,177,74,70,246,196,210,65,133,39,226,102,111,133,177,201,97,60,106,224,159,36,215,120,14,171,134,102,127,59,219,61,254,216,227,241,215,244,183,201,55,100,0,171,128,100,159,25,55,117,234,84,149,235,81,163,70,169,92,219,202,163,133,23,46,92,225,10,15,132,190,230,127,146,236,218,53,59,106,128,222,63,65,48,71,223,245,46,233,42,115,124,215,246,14,142,154,110,73,35,38,147,250,46,202,127,255,162,119,110,126,120,151,138,78,177,2,93,188,142,86,123,154,185,237,182,14,98,162,124,67,222,221,38,131,121,254,234,117,171,255,20,5,44,23,52,254,41,121,23,230,103,147,152,249,62,32,50,101,142,231,141,135,165,13,254,35,108,228,221,8,49,233,250,162,228,221,104,209,73,241,188,131,78,66,58,11,93,97,249,84,120,15,191,10,235,31,118,63,44,255,91,244,162,93,183,35,216,89,249,106,215,50,127,196,71,36,210,108,92,51,31,95,70,176,97,8,196,251,159,26,38,225,76,104,17,1,45,11,245,106,177,54,47,122,184,134,23,50,63,32,164,5,169,50,68,21,166,49,93,255,254,253,37,225,129,238,245,35,27,67,23,65,128,61,107,169,2,168,89,11,236,69,18,119,168,224,99,249,50,246,173,240,11,124,204,62,251,231,63,223,114,103,157,117,150,187,226,138,43,221,184,99,199,105,71,17,150,66,167,57,191,51,18,230,48,208,56,65,167,11,102,75,193,193,22,46,86,13,161,33,179,220,114,203,21,121,131,138,27,26,138,214,65,163,113,151,202,35,76,111,141,31,63,190,232,121,116,102,60,254,164,196,189,255,82,5,113,247,31,212,101,218,82,49,48,219,215,254,189,134,57,111,174,24,101,53,189,54,219,204,242,61,30,207,121,100,70,249,215,95,125,157,216,128,197,32,228,135,31,126,32,54,209,123,68,175,161,114,171,141,26,244,18,37,56,173,252,202,45,191,162,136,125,38,230,149,85,59,152,13,30,111,76,99,166,29,102,116,180,40,110,120,90,90,121,99,102,236,14,59,108,175,102,146,208,152,24,50,100,136,187,251,158,187,101,85,220,154,14,251,17,148,227,6,13,90,206,61,58,249,17,29,16,181,206,205,248,123,239,190,251,174,92,10,10,247,123,144,180,21,198,53,254,86,118,126,203,231,173,121,229,231,69,167,199,78,228,223,58,71,75,249,93,138,217,197,23,93,172,38,48,100,35,222,162,217,234,186,58,43,38,14,161,95,229,203,95,60,94,232,60,55,55,96,192,0,149,63,52,18,101,227,98,187,220,73,71,47,160,4,31,33,199,59,74,71,217,117,215,94,167,186,27,114,60,105,210,36,183,230,176,181,156,108,30,156,240,134,115,144,73,211,249,241,7,194,149,108,77,14,105,130,27,48,160,191,172,116,248,80,247,98,176,206,55,92,175,138,211,164,151,78,127,37,227,209,90,217,109,38,87,210,86,200,194,36,140,170,246,120,36,37,73,105,178,28,126,103,133,194,122,241,197,23,107,249,137,114,214,86,140,152,151,200,47,105,82,23,248,167,126,75,192,105,223,44,242,113,123,49,137,137,217,208,208,125,216,103,3,117,129,97,178,55,75,154,204,88,120,109,57,34,252,196,244,55,123,130,153,190,72,41,204,129,249,179,169,45,140,112,38,124,80,48,17,198,238,249,71,132,131,255,210,152,250,207,226,188,244,115,65,52,248,130,103,7,12,104,155,252,99,245,18,234,105,105,121,5,63,109,112,7,242,133,244,219,234,81,220,139,59,152,54,194,23,96,121,105,223,37,58,124,177,79,68,217,174,80,164,202,123,77,2,182,112,75,189,0,249,243,247,111,137,63,107,250,215,234,120,216,191,5,230,200,208,177,157,182,42,84,203,77,9,127,185,229,6,169,119,120,23,73,40,181,18,17,239,128,149,159,191,208,143,35,70,236,224,174,187,254,186,72,214,177,242,105,141,97,195,74,202,58,6,177,94,121,249,21,183,249,230,155,199,147,83,189,223,72,140,166,168,50,65,194,164,104,90,157,206,66,68,167,38,38,83,224,15,43,31,176,154,15,109,14,76,190,176,65,237,184,254,177,119,75,125,255,97,249,19,104,153,93,142,28,99,224,123,234,11,83,117,32,20,117,65,223,161,157,129,21,53,182,194,207,191,151,118,30,202,136,2,46,122,36,169,254,89,244,144,119,33,45,253,208,3,24,16,198,31,152,97,16,23,29,216,152,176,113,204,49,199,120,62,20,158,46,179,204,64,247,200,35,143,232,96,82,146,89,197,7,31,124,80,7,239,161,183,227,78,39,216,201,69,171,179,199,239,119,244,183,233,3,191,254,211,81,63,43,253,62,86,126,96,96,14,102,72,109,160,197,15,19,147,17,33,231,159,125,81,104,154,13,159,158,165,215,127,30,231,165,210,15,217,254,224,131,176,206,148,20,158,239,215,132,9,19,100,48,232,69,93,197,136,114,222,119,104,251,195,228,216,2,94,219,201,238,167,133,239,235,62,123,182,232,40,233,242,159,131,121,236,114,76,100,195,31,227,97,71,243,219,252,179,163,93,143,31,33,215,24,96,198,202,62,51,3,107,178,154,164,139,202,201,187,133,23,89,180,192,172,158,198,161,68,253,7,249,154,20,79,171,239,161,159,164,28,157,132,137,136,83,95,156,90,34,239,254,93,208,238,53,22,73,97,219,61,232,123,171,31,180,92,11,185,163,252,139,115,183,103,96,86,48,79,147,106,67,6,208,156,116,36,144,29,2,225,247,37,82,153,210,55,149,157,152,50,38,213,38,80,74,255,86,59,46,73,225,117,73,186,152,165,107,165,11,190,44,197,180,114,113,249,229,47,127,169,149,115,116,16,36,57,116,240,172,187,238,58,218,88,53,243,105,254,115,152,149,135,217,113,254,6,212,247,223,127,191,187,68,76,196,109,180,209,134,178,177,228,17,50,211,247,42,247,195,143,63,104,133,215,159,169,137,13,18,209,144,130,61,226,184,67,131,124,198,204,25,110,87,89,41,97,51,73,177,23,11,6,165,78,62,249,228,248,227,250,27,241,195,108,233,129,50,251,21,78,227,190,206,186,169,113,71,60,17,247,2,155,255,250,102,203,63,143,72,7,63,26,166,157,217,17,213,226,123,94,206,146,27,166,89,137,189,86,216,37,138,102,2,39,30,47,152,78,152,35,51,207,252,13,52,237,153,251,238,187,47,156,213,235,37,81,11,93,209,174,77,41,102,200,172,210,107,250,3,29,174,88,37,183,248,18,139,23,13,6,33,28,12,100,98,214,116,225,160,66,24,160,249,97,241,241,143,54,27,30,29,163,216,27,235,135,31,126,108,211,12,249,149,87,94,9,245,119,221,168,214,247,215,63,183,13,173,227,51,237,44,141,254,179,89,62,71,135,107,229,156,228,94,7,42,96,42,31,31,79,215,65,14,232,164,184,195,32,17,242,201,119,38,131,254,53,59,183,188,73,141,147,116,64,195,217,125,172,74,130,44,195,252,166,173,176,49,191,236,8,249,42,181,215,154,61,215,158,35,76,251,64,254,17,6,86,125,34,14,251,236,147,60,251,29,49,199,108,229,36,135,142,249,103,159,125,214,13,28,184,76,180,31,8,6,152,224,96,186,43,201,189,250,234,171,218,217,146,116,175,35,215,140,109,71,252,232,232,187,173,149,221,106,50,70,228,10,51,230,147,28,204,45,165,57,147,177,196,251,210,219,99,233,55,221,183,228,18,75,22,13,6,225,93,149,109,201,251,98,255,90,252,72,10,67,117,159,8,3,246,13,130,204,160,222,96,250,48,233,249,246,92,179,52,164,189,187,253,246,219,235,236,255,107,116,101,102,241,83,208,235,112,88,109,83,202,33,28,252,87,168,255,147,223,40,71,139,249,44,219,34,255,168,103,161,156,130,57,192,52,61,132,240,205,127,243,27,38,111,146,58,129,144,174,155,111,190,89,19,98,239,64,215,116,233,218,213,221,126,219,109,169,171,114,18,117,77,76,255,37,211,105,185,218,90,222,181,60,137,179,192,61,254,196,227,154,246,194,235,225,175,91,100,95,31,121,36,170,227,97,223,51,20,39,87,94,121,101,210,227,122,45,94,110,130,21,242,24,123,71,164,177,210,112,18,124,212,149,64,18,62,202,121,200,58,38,169,140,30,61,58,225,201,150,75,216,24,30,3,13,165,246,44,106,121,186,243,207,218,198,191,125,225,247,93,168,175,195,10,254,56,79,204,124,127,241,197,23,35,29,100,190,99,178,25,246,105,154,45,92,10,7,230,146,133,171,84,26,48,152,1,51,116,119,72,231,112,57,101,38,204,33,33,255,125,51,214,22,47,180,101,208,254,73,250,254,211,226,160,223,83,138,50,176,111,45,237,93,11,183,229,88,168,127,161,3,204,28,152,61,131,193,179,49,99,198,104,45,106,218,180,105,118,57,241,248,187,223,133,251,169,161,62,145,228,238,144,235,232,80,199,222,68,113,103,117,116,51,69,30,191,223,209,223,202,36,86,255,233,168,159,149,126,255,242,203,47,151,85,31,7,186,219,68,103,38,57,236,147,139,118,237,82,50,233,210,156,229,189,29,237,186,127,76,187,23,234,245,192,165,233,35,191,206,244,142,238,45,26,184,112,159,53,223,119,167,245,170,228,111,35,20,220,180,240,11,125,73,254,101,50,158,124,55,253,170,134,41,249,31,15,187,28,255,48,49,0,171,232,225,96,166,206,86,88,217,128,144,201,174,31,186,229,29,6,145,146,92,152,119,51,221,82,50,233,180,208,37,15,172,216,51,73,241,197,36,88,124,167,88,25,233,247,163,216,59,56,250,101,171,214,251,68,245,165,229,29,252,48,211,229,230,71,138,202,9,111,55,127,87,73,113,195,53,173,229,36,180,147,144,23,31,207,248,56,113,197,160,133,155,181,163,166,177,36,140,172,197,152,241,105,24,2,105,163,237,13,3,128,9,45,34,32,122,62,77,255,22,61,91,163,11,153,31,16,82,46,2,178,145,245,62,10,190,245,215,91,79,103,111,135,38,45,138,165,101,164,152,23,64,163,12,131,62,126,5,16,13,139,67,14,57,4,61,8,14,207,192,97,214,44,58,0,123,200,44,95,152,70,130,255,107,203,198,195,176,169,251,146,52,226,124,83,14,232,140,199,204,62,236,137,226,59,204,204,28,45,27,197,138,132,187,145,98,122,193,220,175,127,253,107,61,197,198,188,182,47,134,221,67,252,16,134,4,231,54,242,108,254,239,177,199,30,58,24,128,184,163,161,109,46,138,59,194,104,142,187,221,179,35,120,192,20,17,102,7,107,5,193,110,240,152,41,2,232,8,192,108,120,204,178,75,114,182,162,6,230,4,125,135,1,68,204,36,197,247,175,27,52,251,55,49,117,92,100,163,28,7,251,200,152,105,135,189,7,48,200,233,187,83,79,61,213,61,243,236,51,122,41,222,72,193,197,164,78,2,123,31,155,174,47,43,29,108,104,40,226,91,90,64,194,128,9,128,114,221,209,71,31,173,241,194,158,17,216,148,54,238,224,39,190,193,85,101,115,235,109,182,217,38,186,13,30,185,146,119,124,244,21,114,73,121,86,42,168,164,168,64,62,48,59,248,45,177,197,30,151,15,152,185,124,246,153,80,62,124,127,155,154,164,248,44,83,254,252,247,244,92,59,160,91,242,16,157,191,48,103,243,158,204,80,79,26,76,199,108,96,12,138,183,167,195,189,28,242,144,99,52,102,255,42,157,165,232,92,199,10,16,196,39,201,33,201,87,73,71,172,111,98,3,207,65,23,195,22,58,116,184,63,123,25,215,208,1,141,116,233,198,238,158,167,88,1,131,217,207,27,108,184,129,110,242,237,221,234,240,105,248,125,84,118,24,178,181,72,34,14,232,16,126,76,86,209,196,247,168,192,187,88,33,11,189,120,251,29,183,23,13,150,99,79,63,76,176,128,140,197,117,95,169,239,31,229,44,218,35,166,31,84,182,69,47,193,238,126,92,182,85,247,65,182,203,17,146,88,98,85,102,6,45,231,110,149,193,136,82,50,131,206,86,236,207,227,215,75,98,94,149,254,89,226,27,195,172,236,225,178,79,208,148,41,83,138,6,7,176,25,251,13,55,220,40,43,116,6,184,164,89,242,126,160,24,128,65,103,107,210,32,140,255,28,206,75,68,39,254,168,254,110,139,252,99,53,138,234,161,180,114,74,242,202,15,31,105,219,90,202,5,116,118,99,47,200,184,195,181,87,176,175,129,200,161,213,173,84,215,136,137,33,108,12,158,164,107,80,222,198,117,77,59,196,195,97,245,22,152,166,237,117,101,113,85,217,150,0,208,249,117,136,212,51,49,152,224,59,228,237,77,50,80,13,127,118,218,105,39,189,133,125,41,22,232,209,83,247,196,42,85,110,174,226,149,155,253,251,247,215,50,244,221,119,211,89,189,140,189,59,196,25,43,253,33,255,68,250,81,100,29,101,114,79,209,143,22,23,123,38,126,12,7,35,155,220,6,27,108,16,191,85,149,223,213,208,127,171,173,186,154,152,188,253,58,220,243,196,75,21,246,230,192,4,150,75,47,189,212,187,234,212,188,220,228,201,143,186,159,73,121,128,111,23,14,50,15,253,243,218,107,175,21,60,27,253,240,5,62,186,24,78,38,251,237,142,191,77,149,227,176,204,220,45,42,51,109,53,33,86,191,250,14,3,47,145,57,216,132,206,210,180,250,95,135,202,127,63,2,56,247,62,48,196,7,178,142,114,3,3,138,190,195,42,76,224,176,129,96,255,158,127,14,153,195,42,147,63,255,249,82,93,105,232,223,195,55,15,57,223,78,6,211,147,86,236,194,194,3,38,248,173,180,146,76,86,170,148,139,213,127,42,21,76,103,249,11,115,104,112,24,132,136,175,198,132,254,66,187,22,229,174,223,174,69,185,139,140,77,147,107,228,163,149,209,240,219,119,90,102,136,89,49,228,85,124,95,23,212,153,54,149,58,211,134,27,110,164,126,47,33,122,22,46,77,174,85,180,138,42,189,232,154,74,15,95,61,44,241,15,252,76,139,123,137,215,90,110,37,124,103,184,233,125,6,45,207,202,25,190,3,12,240,99,223,99,240,220,80,228,27,109,39,115,144,85,200,108,82,251,82,243,78,210,159,150,119,96,141,201,136,216,183,203,156,234,36,249,145,150,119,105,233,71,217,138,246,223,251,41,101,43,116,210,110,187,181,212,227,109,149,125,90,222,33,62,113,253,147,162,14,195,168,167,112,13,111,166,243,197,42,42,76,70,233,124,235,4,22,114,231,31,85,254,4,70,71,228,184,243,99,69,31,27,157,128,181,191,26,157,3,211,95,76,32,173,124,43,126,178,54,87,50,111,50,206,176,204,105,165,160,179,231,234,245,8,243,44,183,221,126,135,238,87,130,70,118,220,193,206,249,157,50,43,229,78,49,101,129,25,112,24,152,193,204,23,116,84,163,129,129,13,138,205,220,6,26,63,24,108,65,5,11,141,36,115,168,124,222,115,207,189,218,177,128,247,49,200,130,193,36,204,168,196,204,200,143,62,154,46,251,106,108,236,208,73,143,107,152,225,135,229,234,126,195,1,29,255,48,69,135,13,38,113,142,10,6,252,66,167,45,102,171,97,214,224,50,203,44,19,109,68,141,176,209,249,128,10,17,102,213,12,27,182,166,60,191,133,206,132,71,39,153,197,29,239,36,57,52,206,209,129,128,153,194,141,238,178,172,108,48,147,11,75,232,81,97,71,129,25,175,228,162,3,1,178,116,145,152,237,194,96,35,26,180,176,61,143,142,70,84,154,55,145,6,208,163,143,78,142,178,56,28,4,144,70,77,138,94,136,55,86,240,27,13,3,116,80,192,236,226,214,91,111,237,176,81,245,148,41,143,137,191,143,184,221,118,221,45,218,12,214,2,49,63,210,194,176,231,208,73,143,85,118,159,203,94,86,99,228,219,178,89,107,118,191,212,17,157,34,72,55,190,73,116,58,97,80,20,223,19,236,57,163,195,29,131,65,48,201,248,39,49,45,96,204,16,31,84,130,91,139,87,169,112,171,121,15,241,108,66,156,83,242,170,163,113,41,55,159,44,156,164,104,152,124,92,118,217,229,49,249,152,162,166,137,118,17,253,122,227,141,55,153,23,122,132,45,245,52,103,113,74,187,159,116,29,43,43,31,122,232,97,135,78,122,116,102,111,182,217,102,218,16,70,135,58,204,28,246,147,205,173,207,57,231,156,164,87,75,94,43,87,86,48,73,224,200,35,143,114,159,125,254,185,202,35,102,16,39,58,81,52,27,109,188,177,126,163,144,87,204,214,135,153,25,216,97,127,69,86,251,160,97,237,15,224,163,243,234,80,41,71,176,49,54,116,0,238,13,24,48,64,109,222,223,43,155,123,207,144,153,137,104,40,219,160,112,98,152,237,190,88,251,111,5,166,84,48,139,29,186,44,94,118,99,239,27,216,141,199,42,220,85,87,93,85,77,2,161,51,2,157,224,119,220,121,135,59,241,196,19,117,197,173,63,152,212,218,247,15,61,129,60,55,167,178,45,38,92,97,106,200,116,31,102,127,163,227,15,58,21,229,47,54,65,46,250,62,203,40,80,66,153,57,82,205,70,33,109,73,50,131,103,48,139,249,61,49,93,230,215,55,44,126,254,17,38,165,96,206,9,113,198,159,173,136,131,46,52,118,200,209,163,68,78,173,62,3,83,74,24,56,219,71,246,115,193,42,234,161,67,135,234,224,215,21,87,92,33,105,154,163,131,6,102,154,207,15,203,63,199,192,28,204,183,148,229,132,75,17,171,216,139,254,247,223,86,249,71,57,133,188,218,108,243,205,220,86,191,217,202,33,175,32,15,147,39,79,9,243,234,198,194,188,194,128,53,238,31,35,29,100,224,4,147,92,168,19,129,5,254,142,144,250,216,31,164,62,230,119,46,163,174,7,157,114,218,105,167,235,68,4,232,26,152,23,66,249,28,234,154,126,202,205,146,21,214,191,203,16,8,123,65,142,229,50,213,73,78,34,176,248,78,30,124,240,239,90,103,196,202,5,152,80,197,126,47,186,159,153,248,135,114,210,76,30,163,220,60,255,252,243,116,207,12,116,156,67,134,147,202,77,124,87,86,110,34,106,198,10,157,137,96,133,122,6,88,193,12,17,6,112,142,148,129,38,200,83,210,196,43,172,18,210,114,94,204,66,141,217,119,76,180,71,26,252,141,59,12,40,161,126,61,104,208,178,90,15,142,223,175,222,239,202,234,63,240,195,222,140,144,51,127,5,51,76,155,97,159,37,240,194,138,81,180,73,208,230,64,61,255,203,47,191,210,50,192,246,168,129,188,46,208,99,1,93,121,5,253,129,78,85,76,222,241,247,97,76,251,222,194,50,243,161,176,204,20,179,216,155,138,28,67,87,162,204,68,156,80,199,179,129,82,200,20,244,41,218,46,144,119,180,111,208,134,65,187,4,101,24,228,64,106,42,81,214,216,55,156,22,118,167,150,255,34,255,22,14,210,191,221,118,219,201,64,251,173,250,45,111,185,229,150,186,170,29,223,56,86,57,244,91,184,159,67,125,185,148,67,220,209,54,130,73,173,173,182,218,74,219,71,88,81,5,153,199,170,83,156,27,23,223,31,212,205,241,253,163,156,110,75,61,214,247,163,30,207,135,137,121,72,76,138,196,132,181,254,3,250,187,53,134,174,161,101,41,100,6,60,49,249,113,73,25,196,243,205,158,67,174,123,244,152,95,229,26,166,210,49,200,23,151,235,52,86,40,51,48,80,129,137,98,104,67,99,210,36,202,59,236,19,116,239,125,247,202,170,188,25,58,32,130,58,19,116,34,194,189,85,86,96,111,38,150,16,32,215,104,55,163,61,141,111,18,113,148,70,87,90,80,69,215,77,14,77,254,227,15,64,163,148,91,167,140,191,235,255,142,251,143,112,241,253,93,112,193,5,170,39,112,31,113,199,36,22,76,36,10,235,237,129,236,181,51,218,93,120,193,133,5,122,29,122,99,104,115,251,18,254,248,126,35,239,14,146,213,93,48,197,138,122,231,26,107,172,161,147,144,48,65,101,210,164,187,37,239,94,214,54,38,116,131,57,213,73,61,23,208,213,181,240,27,38,198,49,120,10,157,20,198,179,229,123,181,119,236,136,250,59,202,19,148,53,152,172,128,9,79,40,79,252,178,213,234,241,248,206,145,119,88,225,139,186,153,233,36,152,36,133,78,210,21,66,241,6,75,27,235,31,22,47,139,183,253,246,143,248,230,225,160,207,243,226,144,30,115,254,185,93,227,145,4,106,65,32,222,254,170,69,28,24,102,182,8,152,126,106,209,88,217,138,95,20,27,137,104,166,157,204,8,17,134,77,129,116,150,102,58,158,149,142,156,84,94,2,233,24,15,150,29,56,48,144,25,73,137,193,73,229,41,144,74,107,176,196,146,75,64,238,130,174,93,186,4,210,72,14,164,115,33,122,94,26,189,129,204,92,10,164,113,20,93,243,79,158,121,230,153,64,236,200,6,82,25,137,46,203,12,165,64,58,99,2,169,144,234,154,12,177,143,27,72,37,53,144,14,174,232,25,255,68,26,195,129,116,188,7,210,33,160,241,64,92,240,39,157,95,129,52,100,2,177,243,235,63,174,231,82,241,9,227,190,68,24,119,169,208,21,197,61,254,146,52,94,2,25,40,10,164,147,41,64,152,141,234,190,249,230,155,102,206,77,129,116,116,100,22,131,116,28,168,252,72,67,37,49,142,210,136,15,196,156,77,36,51,210,152,15,100,179,212,64,76,49,4,82,17,15,196,44,64,128,60,135,147,129,69,149,39,153,245,149,232,151,116,66,168,156,75,101,59,186,47,131,44,129,152,27,8,100,38,153,134,209,69,100,76,26,190,129,84,198,3,49,129,165,254,73,103,65,244,188,116,0,169,31,98,134,32,186,150,116,130,248,137,153,0,241,179,41,144,14,172,164,71,90,189,246,220,115,207,5,210,24,8,164,17,94,144,126,233,28,12,102,206,156,89,240,190,152,25,208,120,225,91,207,131,147,205,155,53,77,210,40,174,72,116,165,1,169,121,39,166,124,90,245,95,58,141,83,243,84,58,68,85,62,164,243,56,148,15,209,159,190,124,64,111,250,242,129,188,193,53,124,127,113,135,252,196,61,233,176,138,223,210,223,178,218,43,232,45,247,161,247,124,39,131,160,129,52,18,245,93,211,155,131,6,45,23,200,160,65,32,157,87,254,163,101,157,75,39,146,250,85,142,94,144,129,254,64,42,179,154,118,217,151,45,209,255,225,91,110,169,247,33,243,98,50,41,144,206,43,253,141,184,74,163,57,56,238,184,227,82,117,177,116,236,6,203,201,247,13,221,142,231,231,23,89,151,149,27,129,152,125,74,12,171,163,23,39,78,156,24,197,77,26,227,29,245,174,221,239,91,217,141,242,48,169,236,134,220,201,128,112,128,239,3,92,160,75,32,119,210,161,28,188,251,238,187,34,219,11,6,50,193,34,10,31,186,15,178,5,214,73,78,6,71,2,25,84,10,146,116,223,60,190,108,75,25,110,186,15,254,225,220,156,12,226,104,24,229,232,62,147,25,200,124,146,67,93,1,254,183,230,23,222,149,149,68,250,44,158,183,63,164,63,58,111,190,46,230,184,10,130,18,83,163,129,116,242,6,210,105,131,62,37,149,99,233,12,11,100,208,171,224,185,142,254,48,246,105,229,142,126,247,189,123,5,210,185,84,20,84,185,242,143,114,74,58,212,131,22,61,20,202,131,159,87,190,30,66,64,208,13,178,87,77,32,29,142,81,250,101,128,49,128,78,124,227,141,55,148,95,60,206,50,241,34,65,215,12,74,212,53,229,150,133,69,137,46,227,2,202,125,228,175,12,222,4,208,87,40,7,165,147,83,191,5,28,165,67,47,64,121,158,228,192,91,6,132,2,89,85,37,207,135,122,69,58,204,3,217,195,178,168,220,180,247,33,43,91,108,177,133,234,31,251,222,192,74,76,235,165,178,194,187,90,206,183,162,31,45,12,212,141,209,111,135,122,112,173,28,202,18,164,15,127,50,0,88,145,104,200,32,163,234,26,240,139,59,49,247,28,224,27,180,56,224,8,157,63,118,236,216,0,58,207,119,224,36,157,224,250,44,244,9,202,64,56,212,117,240,253,163,221,144,230,144,78,153,16,166,241,208,176,228,251,23,19,145,137,114,140,246,143,133,131,252,145,201,54,129,12,38,106,25,14,61,133,63,115,246,173,167,233,89,89,65,171,245,14,25,128,178,87,162,163,76,232,80,153,150,206,225,232,90,218,73,82,56,224,42,147,241,180,205,101,114,141,227,234,18,63,124,47,229,58,148,123,98,253,33,250,158,250,72,219,14,109,63,48,75,114,208,191,96,120,230,153,103,38,221,238,148,107,98,129,66,195,0,255,164,182,96,167,4,82,1,79,208,198,148,73,3,218,230,52,57,195,17,186,11,237,10,232,135,184,131,92,203,224,91,36,215,219,123,114,221,75,202,232,82,114,13,191,80,102,160,254,23,150,177,77,65,15,209,115,73,117,38,49,251,26,201,53,202,63,180,149,76,174,241,109,250,114,13,127,161,31,17,126,82,221,21,117,63,164,169,100,221,85,218,242,168,215,180,199,201,192,140,250,47,147,80,10,94,151,193,54,189,110,101,189,29,251,247,31,160,253,63,208,27,98,42,177,224,29,255,135,12,192,40,103,25,224,245,47,235,185,229,221,64,233,47,208,188,147,124,131,252,33,12,148,181,168,251,198,93,75,222,53,41,127,95,39,225,189,82,237,175,180,178,117,47,169,199,203,10,179,130,160,160,147,100,96,47,138,151,175,147,144,119,168,11,154,51,93,17,47,203,237,190,234,164,5,123,7,50,0,101,151,162,163,12,78,105,155,227,148,83,78,137,174,217,9,194,64,191,15,244,78,94,28,234,54,150,151,178,71,118,94,162,205,120,214,57,1,153,180,161,114,9,253,242,192,3,15,212,121,106,153,188,114,8,200,10,204,72,38,196,242,71,57,175,212,228,25,204,118,200,180,11,7,132,92,176,94,131,15,8,33,147,80,97,66,1,40,51,239,90,205,51,116,16,200,222,1,173,62,215,214,7,208,152,70,135,69,185,14,21,12,116,72,180,165,226,95,110,220,101,6,28,166,2,5,50,115,180,220,232,212,229,115,50,139,90,59,129,32,27,98,74,37,179,105,132,12,160,227,70,102,139,150,140,163,44,93,15,100,70,88,201,103,58,114,19,157,178,232,104,21,211,137,29,241,38,122,23,149,81,52,194,226,141,174,232,129,54,156,96,192,11,3,176,73,13,148,54,120,147,169,71,247,28,85,217,1,161,206,78,44,26,143,157,41,31,237,141,31,26,142,178,242,166,189,175,183,249,61,149,99,209,33,165,228,88,102,43,75,25,212,20,224,27,53,7,125,157,212,25,98,247,227,71,148,9,98,190,44,117,224,40,254,124,123,127,135,3,66,77,50,0,229,180,163,185,189,254,116,198,123,232,4,129,126,78,155,68,129,48,32,119,248,246,161,207,43,236,189,9,60,212,237,187,48,158,165,100,18,34,109,194,183,40,251,190,19,145,189,108,89,147,52,198,204,23,147,49,51,102,177,51,164,82,169,144,66,132,74,74,217,74,11,18,90,237,82,100,41,91,101,95,162,236,187,255,103,22,140,234,233,233,57,231,61,231,61,231,253,63,243,123,62,154,185,239,107,191,175,251,186,174,251,250,222,51,191,78,206,83,177,87,123,21,90,66,47,152,221,116,123,84,103,175,102,33,206,51,129,155,213,155,126,123,230,234,251,29,22,111,102,234,188,111,29,153,194,132,243,239,251,176,102,235,254,190,30,241,203,74,254,47,237,196,240,50,121,172,106,55,154,77,75,198,47,197,59,158,244,213,207,75,55,174,183,133,6,184,138,94,98,248,34,213,165,28,162,183,217,225,225,45,220,22,246,181,39,167,165,239,112,223,67,236,252,136,229,142,90,111,190,16,89,176,159,187,141,235,192,234,231,241,152,194,59,76,47,148,174,11,127,215,206,91,187,245,156,217,69,67,63,165,94,181,242,74,220,199,109,34,69,0,52,227,181,176,232,185,99,80,157,184,183,167,206,114,220,120,180,139,63,194,168,212,215,173,247,245,167,13,107,46,139,191,243,124,56,153,136,125,193,90,179,85,128,189,53,58,202,118,252,104,244,133,210,117,29,70,121,99,242,123,26,54,228,233,123,119,190,191,2,52,136,44,28,174,232,150,184,63,144,158,123,169,169,240,161,230,25,220,72,230,97,53,214,182,35,146,132,154,16,14,205,84,98,238,195,224,161,55,229,73,111,198,13,198,157,106,230,5,222,239,5,59,225,46,126,102,11,134,215,28,152,101,62,111,149,59,179,215,223,158,32,4,136,159,22,188,242,236,85,78,250,19,169,157,15,63,120,202,85,138,157,95,127,255,59,36,241,252,87,199,83,12,183,54,223,35,56,108,251,182,11,246,108,32,168,210,73,116,202,216,15,253,162,227,128,189,49,171,227,157,61,74,178,209,31,132,65,22,91,211,230,200,64,137,59,80,203,232,16,248,131,106,125,79,57,63,227,179,252,254,34,31,60,35,24,36,242,98,46,184,200,174,31,113,60,134,128,201,149,85,50,164,104,190,15,230,253,84,87,68,34,177,224,77,248,136,50,171,87,89,234,59,196,61,185,107,148,126,97,154,197,146,133,105,13,155,185,188,7,223,152,184,252,80,90,223,166,169,202,51,236,37,183,238,37,236,18,224,43,99,138,221,114,191,10,167,254,197,76,117,40,110,187,206,188,227,209,135,15,197,37,194,174,103,53,101,51,40,150,51,199,70,49,118,151,171,159,17,159,207,186,63,240,92,168,227,176,91,230,29,208,230,240,135,245,252,147,227,48,155,91,22,236,176,103,204,46,46,189,154,61,248,203,87,70,14,71,93,217,159,146,250,22,122,147,163,11,172,218,110,253,185,5,53,43,102,59,31,25,253,184,111,199,37,247,136,29,3,58,239,55,133,98,182,220,50,122,240,197,241,11,135,218,62,155,228,24,158,20,154,7,168,166,223,228,62,216,47,181,182,251,42,254,236,196,177,97,65,214,145,152,26,187,129,123,87,124,190,118,222,27,158,230,152,185,93,217,144,145,31,165,45,44,160,67,96,183,60,144,237,84,34,249,184,209,105,245,173,171,55,88,158,114,151,2,227,140,200,44,157,43,118,166,246,76,68,227,210,205,195,242,253,236,200,125,188,98,101,219,93,242,60,74,38,152,237,164,47,183,134,190,70,109,52,46,191,158,126,87,183,233,221,151,179,217,42,10,106,206,182,195,94,186,71,1,179,242,140,164,207,121,23,74,21,95,136,223,126,195,156,167,63,101,43,150,52,98,144,255,116,75,123,126,140,117,255,224,25,225,36,243,145,36,36,198,46,73,55,207,199,86,50,225,4,38,115,147,90,239,251,90,83,98,75,119,255,209,135,102,132,109,69,198,14,152,204,6,229,27,79,93,196,4,182,92,57,29,212,86,63,90,157,204,226,93,131,101,6,88,108,106,43,179,141,17,36,173,181,1,102,195,6,39,135,30,50,85,161,230,114,92,240,223,125,167,33,176,234,128,55,87,147,16,208,112,222,180,247,247,99,29,124,175,31,127,110,112,177,69,229,112,37,226,78,62,122,183,196,238,77,92,95,71,155,240,118,123,203,211,77,30,157,15,15,224,184,55,244,250,57,139,192,77,191,85,160,70,235,163,176,36,177,239,31,87,87,71,112,179,110,44,253,94,33,221,155,232,209,159,254,192,244,203,131,249,215,123,46,151,164,238,123,255,241,58,126,97,141,104,26,194,250,184,206,135,203,46,194,105,39,136,213,137,27,170,158,112,204,176,69,11,202,251,152,202,183,183,198,50,239,180,139,57,255,226,224,27,157,250,251,46,7,227,94,22,30,217,98,94,194,47,221,56,179,107,93,102,205,52,71,20,195,133,189,243,42,19,141,237,225,170,3,77,122,49,123,25,27,189,144,69,115,19,181,5,22,50,215,236,120,132,191,94,222,83,39,120,247,197,137,96,194,233,160,116,156,71,152,196,211,211,21,126,51,217,58,156,31,191,101,167,31,242,10,215,28,78,229,37,213,76,42,153,244,29,211,225,180,246,81,168,72,72,183,102,120,166,37,167,247,236,201,23,145,152,43,229,209,113,250,183,106,198,190,189,49,60,226,83,59,164,38,120,115,124,26,6,181,241,107,203,122,48,33,51,99,25,125,162,223,57,132,24,253,80,105,151,193,120,194,91,147,128,138,132,206,218,221,213,248,105,44,191,38,79,165,113,73,87,75,227,39,91,99,3,33,52,42,158,101,182,63,35,167,208,111,97,110,66,232,174,9,186,234,81,253,251,243,151,71,56,135,14,23,71,94,78,62,92,99,198,158,175,119,33,33,83,83,163,253,156,252,69,129,135,105,85,251,119,67,125,174,172,175,58,36,13,230,12,124,223,249,100,8,186,115,67,176,189,165,141,6,204,210,71,141,43,213,128,177,31,3,100,207,183,206,196,41,164,127,115,51,169,191,127,38,63,150,151,120,200,227,50,159,173,207,156,240,140,95,105,113,79,206,147,251,240,112,108,246,222,40,118,9,132,240,220,57,35,55,102,243,205,164,246,49,229,230,155,70,81,98,79,212,82,1,254,26,157,139,89,190,186,218,3,83,130,33,204,55,198,59,61,167,208,80,27,166,175,163,189,181,224,235,105,152,233,56,7,46,148,223,215,85,241,120,186,214,22,139,199,214,133,222,105,90,79,123,65,13,110,243,16,13,153,115,113,33,60,165,99,87,57,140,237,155,214,34,72,90,169,62,135,206,243,148,68,159,115,15,243,73,140,206,233,235,151,176,95,63,248,49,251,17,38,185,216,38,178,252,212,189,42,165,166,211,31,46,227,175,162,158,222,89,255,98,207,166,56,131,237,178,245,101,133,162,166,74,76,196,236,235,30,31,110,185,151,159,178,50,224,136,243,207,110,77,44,48,214,24,46,21,108,174,188,34,159,128,122,248,245,222,199,12,69,110,147,38,247,252,4,123,231,94,84,124,135,216,45,54,203,246,15,17,133,190,34,249,239,166,196,61,199,172,157,61,155,61,12,110,239,62,16,118,125,4,194,218,145,248,108,131,220,179,96,220,81,165,83,94,17,196,244,81,241,78,199,192,204,237,220,132,148,217,158,89,191,203,13,36,17,229,204,188,174,195,138,81,19,125,105,89,56,173,212,17,249,251,78,154,135,231,216,136,195,159,95,134,218,74,92,21,10,127,96,33,37,252,250,124,195,176,145,86,83,12,169,212,107,38,123,91,7,212,239,171,162,50,174,131,159,189,222,249,112,218,132,173,160,230,87,86,157,199,153,21,97,187,134,199,133,194,135,58,34,130,162,111,215,96,214,127,184,41,200,192,169,165,193,162,193,105,23,115,122,128,99,173,104,21,167,136,105,175,97,16,51,132,181,227,254,65,226,228,231,208,205,187,119,186,20,57,94,12,202,220,195,40,150,100,177,237,241,161,131,146,67,26,154,214,62,140,141,49,153,146,232,247,169,7,221,125,246,48,85,59,195,1,17,38,64,77,18,114,190,208,5,122,59,248,166,193,21,225,136,5,92,161,239,52,102,170,51,198,139,123,183,113,169,127,162,220,241,147,204,230,123,213,103,6,30,172,147,182,233,140,33,92,233,4,55,217,91,123,203,68,188,217,25,49,49,14,186,120,136,116,86,239,142,71,125,249,22,227,18,202,94,223,119,25,235,179,251,117,174,109,88,208,88,137,182,146,93,161,117,152,239,248,75,214,153,162,108,13,161,75,225,12,59,64,195,71,73,1,145,46,108,70,65,204,134,215,98,181,162,122,190,157,147,168,17,185,176,61,235,189,108,240,61,198,226,179,62,124,46,178,81,250,140,66,17,251,130,166,165,87,179,73,55,156,214,58,96,119,100,234,178,155,226,254,157,33,187,24,184,82,215,48,244,110,98,59,144,123,140,185,88,198,240,26,145,81,9,56,33,60,55,82,223,214,193,61,182,31,72,31,65,20,73,181,238,218,187,85,235,81,82,210,83,39,227,52,35,64,140,160,226,124,216,100,128,45,109,61,243,190,175,38,12,238,76,114,154,31,181,25,35,143,110,36,29,86,187,174,214,35,10,21,102,224,2,130,183,115,94,155,175,208,222,173,232,184,177,234,149,200,177,16,137,24,94,243,85,177,8,174,30,9,198,154,123,175,16,58,106,92,165,144,96,85,124,215,137,131,48,47,3,155,236,155,93,223,215,246,171,94,215,58,52,119,187,43,114,255,105,173,46,150,19,175,246,165,234,198,67,109,246,181,126,231,98,21,9,78,61,248,218,100,64,100,195,86,33,206,50,151,53,237,197,34,117,210,12,208,193,236,35,172,105,109,219,29,203,13,131,152,143,233,5,77,103,217,116,108,69,139,50,138,197,212,220,188,205,250,217,226,146,119,56,179,225,181,141,12,226,109,169,6,251,15,126,41,56,198,125,239,140,202,117,235,141,227,14,182,241,164,77,47,71,102,4,140,49,160,92,162,221,185,75,2,183,253,81,175,59,74,98,187,133,204,29,24,37,33,167,44,193,187,7,18,175,63,58,169,197,169,80,125,21,89,113,192,63,154,89,109,223,181,60,205,214,27,130,234,95,182,182,237,162,232,183,225,218,124,197,65,103,69,125,171,71,18,245,183,32,77,226,231,35,219,141,119,177,18,52,25,250,189,187,185,174,191,113,57,32,160,110,26,148,98,95,178,181,62,140,3,182,160,35,178,193,110,48,172,116,22,114,221,119,195,218,91,33,204,98,122,192,221,45,70,171,236,108,148,46,239,39,21,76,169,19,251,172,188,234,172,109,243,204,52,167,110,74,93,116,126,32,24,247,4,251,216,216,1,225,106,202,117,221,247,96,191,163,92,198,77,6,229,123,113,170,248,91,125,145,155,161,254,178,194,170,54,11,239,102,135,43,164,229,175,148,42,183,122,191,108,241,237,207,24,124,220,132,78,139,199,177,92,131,122,127,94,237,85,165,216,144,107,182,119,78,33,170,89,156,255,206,154,122,18,143,75,197,170,143,122,90,21,78,54,171,155,94,95,144,142,92,197,58,201,172,27,105,184,181,225,244,152,95,18,99,245,3,35,64,78,32,166,170,71,214,198,122,231,91,139,238,50,79,168,110,23,203,137,198,231,14,187,206,128,50,121,187,158,149,155,163,31,72,201,126,113,200,247,36,194,139,207,121,204,12,170,239,254,30,216,42,165,127,249,6,246,184,110,235,141,234,201,174,75,65,117,124,113,55,95,187,118,171,154,236,207,191,81,48,84,56,115,151,31,217,80,225,47,122,249,153,217,222,185,142,55,123,70,140,149,93,223,2,94,239,15,26,164,104,186,40,39,122,127,97,205,169,82,106,202,61,185,233,112,169,100,99,126,14,175,28,226,180,122,207,181,144,237,107,96,217,159,56,99,158,135,176,228,111,16,212,207,253,154,211,214,170,49,251,237,165,221,105,155,219,175,24,192,222,158,128,113,143,100,131,240,193,141,11,195,61,70,201,125,69,123,186,172,95,190,202,243,185,150,13,171,169,56,113,113,21,43,65,44,248,158,169,128,146,88,178,146,243,237,83,90,213,134,215,230,152,101,88,34,3,240,95,187,109,205,48,119,51,185,172,79,62,241,142,118,232,98,57,49,16,146,13,143,134,201,161,133,204,215,49,158,175,255,112,166,188,45,124,239,252,161,117,239,173,89,241,39,121,108,176,6,2,1,15,243,219,47,52,181,188,58,195,157,198,229,188,139,73,182,197,189,100,255,41,189,34,35,192,116,149,82,49,175,137,65,43,174,66,114,240,141,250,16,174,100,59,254,156,61,50,229,242,23,195,253,243,197,65,37,28,123,103,205,135,175,232,23,76,85,147,230,107,51,114,90,125,203,199,36,85,147,52,3,124,141,54,110,57,242,129,80,91,213,28,194,161,217,83,15,37,5,120,53,126,14,205,31,108,201,207,15,147,46,108,116,207,253,124,74,17,122,126,164,82,190,58,119,239,254,35,155,160,78,30,94,99,117,182,249,182,208,128,58,247,251,175,55,237,170,189,116,59,94,60,51,247,134,250,225,194,96,245,193,220,151,159,227,93,117,27,78,79,103,109,24,81,37,33,223,120,118,27,206,123,203,21,11,189,85,97,158,29,191,73,106,85,97,142,173,145,224,94,155,123,219,43,250,193,237,187,30,15,230,67,211,27,188,229,246,2,39,142,188,236,195,49,29,174,59,130,112,20,138,96,98,252,156,179,225,163,163,235,137,179,239,68,111,95,253,50,61,214,31,19,114,21,73,218,24,174,62,168,146,211,140,171,200,11,225,208,108,172,74,212,200,159,227,7,59,76,6,86,27,240,37,70,86,186,70,184,166,62,213,150,44,31,76,60,127,109,179,164,253,117,105,246,61,223,180,148,189,243,180,209,205,185,30,158,121,3,237,119,110,39,246,109,58,234,253,57,59,9,115,137,69,186,104,22,151,51,92,46,158,31,115,212,183,76,123,111,142,77,222,194,116,127,86,139,141,61,166,179,139,121,111,111,16,167,113,118,2,254,141,234,160,192,194,100,104,19,216,157,208,82,34,64,26,144,122,210,115,35,238,139,223,112,153,176,226,172,134,193,96,175,254,133,237,189,129,223,195,160,185,171,55,29,186,118,203,163,111,224,89,164,109,72,12,111,122,90,118,223,117,9,201,24,179,228,190,34,220,212,183,188,143,27,214,218,139,163,26,26,164,88,182,200,177,190,103,98,120,39,52,89,196,96,178,175,65,103,176,14,191,45,87,46,63,17,159,227,142,172,8,11,44,127,29,196,233,156,251,46,114,21,171,16,119,80,54,242,162,169,89,174,126,15,161,68,226,171,175,23,190,90,35,199,83,205,105,136,137,160,219,213,114,230,93,230,83,225,224,239,213,91,25,50,78,104,15,116,72,75,243,100,191,209,98,11,248,254,193,37,41,207,163,102,3,187,70,141,205,68,189,61,70,89,87,181,198,70,234,118,130,103,156,189,91,198,163,22,241,172,167,95,198,219,72,11,54,208,133,182,133,57,168,114,127,188,221,224,67,203,239,173,135,87,87,67,177,159,79,14,214,28,144,38,230,127,125,108,255,124,236,241,108,35,174,66,178,5,19,56,18,255,248,169,197,232,192,185,173,242,86,242,89,217,229,98,122,19,125,157,140,133,193,30,37,231,107,3,78,72,229,15,100,251,26,217,164,245,126,27,131,166,113,140,48,112,165,238,100,72,91,175,100,145,119,68,239,41,219,89,230,109,39,130,92,185,44,119,175,191,232,180,91,94,128,89,36,122,170,244,246,177,87,114,210,99,87,147,172,153,244,13,94,172,13,61,190,13,207,17,116,1,219,158,127,94,15,72,141,170,233,254,94,34,224,213,200,204,199,180,227,208,142,7,31,156,227,243,90,179,135,24,183,143,31,153,108,40,154,239,188,101,154,208,87,184,48,239,151,64,116,207,99,27,81,111,11,152,72,240,235,187,115,155,16,61,82,77,154,199,79,204,207,12,229,231,15,62,169,32,246,215,87,125,45,152,104,29,79,229,95,152,27,34,229,27,8,4,188,47,24,255,232,246,100,243,171,99,105,25,93,211,19,67,208,111,231,230,38,135,72,11,253,137,164,121,159,137,129,7,213,119,69,83,130,153,88,238,230,37,241,107,248,54,10,250,190,90,83,127,186,33,206,45,243,206,238,175,156,155,7,4,24,184,177,188,238,15,35,227,93,18,125,110,116,203,170,207,6,179,240,191,37,72,21,205,14,15,146,230,187,73,205,213,129,54,169,23,188,62,34,133,189,158,18,250,18,73,243,83,131,65,76,236,88,124,149,162,237,104,96,162,233,13,237,253,23,250,187,69,155,250,196,50,35,217,234,173,239,158,229,102,178,140,235,78,244,203,236,147,235,9,207,13,209,60,62,47,145,2,133,122,127,246,153,72,90,152,21,174,201,74,173,124,97,188,77,173,254,187,148,77,225,39,229,202,242,185,182,133,185,164,76,239,231,243,242,111,27,186,158,241,138,35,175,193,243,9,189,55,196,221,108,160,1,99,140,124,174,213,59,37,38,215,141,128,223,228,77,138,2,199,234,108,167,217,42,131,96,171,185,43,31,205,205,13,145,188,114,53,253,39,177,202,142,207,86,141,200,213,20,133,107,140,199,218,35,34,245,154,159,244,103,246,71,219,57,95,233,209,52,45,156,252,178,142,165,229,194,76,167,10,219,67,109,179,151,143,156,197,216,171,143,224,171,20,227,198,111,250,247,52,229,96,66,39,30,93,81,116,179,201,103,81,147,189,243,165,96,162,21,175,226,52,214,165,62,244,52,121,170,37,205,86,58,212,127,186,43,30,3,41,183,216,163,142,172,185,121,35,123,52,57,92,179,166,251,150,73,252,45,63,161,140,251,197,219,226,26,12,139,134,204,149,118,38,133,174,231,221,212,185,30,177,193,231,76,118,190,213,135,220,222,91,241,106,3,171,47,117,164,111,55,152,172,144,202,79,63,32,94,242,72,66,227,179,183,50,236,5,179,131,232,70,105,183,168,217,46,69,46,32,184,156,83,203,58,130,91,67,252,101,116,225,197,85,172,17,171,88,223,95,208,58,84,88,39,229,127,234,170,36,227,199,133,8,150,235,17,167,157,63,26,185,220,141,123,22,189,38,224,86,123,89,105,164,86,198,90,195,238,245,167,66,70,205,148,242,50,173,21,212,182,103,18,62,186,110,187,25,34,182,63,156,192,188,218,105,6,58,215,234,146,20,112,163,63,250,104,111,197,241,148,250,79,33,28,154,107,249,125,58,54,212,241,108,62,130,213,190,55,51,152,31,90,93,30,208,43,114,238,203,238,4,139,224,216,239,172,159,48,61,6,91,108,26,146,136,235,77,85,62,159,208,82,179,74,118,241,192,181,250,116,175,198,87,203,123,29,204,61,32,113,95,23,96,210,92,93,93,174,101,254,150,164,181,240,169,74,185,141,109,122,180,151,247,100,56,182,43,137,52,255,105,48,127,168,190,27,180,201,237,134,110,153,63,236,150,197,99,200,2,6,147,38,61,106,140,132,145,113,136,107,233,61,71,143,74,157,219,166,184,191,86,156,9,239,115,70,174,221,142,133,25,177,32,57,231,249,109,206,36,113,79,30,187,197,123,95,46,196,42,221,162,71,223,219,75,54,107,176,205,137,17,107,78,179,230,18,122,107,110,64,13,194,249,51,134,166,167,109,137,55,123,204,123,108,85,182,54,178,35,222,2,156,15,92,158,31,95,39,149,26,248,217,103,235,236,233,23,249,11,243,51,97,163,2,179,27,240,136,224,244,204,51,137,47,207,176,29,93,45,247,118,227,84,72,247,39,129,209,180,88,121,113,111,155,53,111,21,3,215,30,48,254,210,155,215,75,122,26,154,91,54,111,240,28,95,173,177,121,116,80,210,35,202,45,55,60,153,77,133,185,225,168,159,123,48,73,238,155,208,68,28,227,21,21,115,108,193,85,1,57,206,27,243,251,98,110,171,158,80,69,85,193,144,57,234,254,14,227,66,16,165,70,199,16,207,41,252,91,109,150,147,254,66,115,197,172,205,164,177,52,232,29,146,92,196,237,6,112,85,74,138,4,207,5,155,232,114,173,195,247,222,168,245,111,236,136,159,98,10,16,240,202,222,39,22,193,186,57,216,184,111,237,244,232,215,218,237,74,195,183,140,42,138,253,6,243,12,160,12,213,185,179,25,121,245,113,122,160,96,249,247,140,156,86,181,158,154,71,7,158,143,76,6,124,57,35,188,233,114,251,183,237,160,104,199,222,106,16,121,213,237,78,91,246,180,248,197,133,40,51,205,188,247,201,79,13,24,173,5,177,179,223,75,12,218,138,210,17,25,135,115,217,78,51,27,94,11,92,219,76,168,53,57,56,151,124,176,124,116,186,172,96,218,228,204,128,237,157,177,195,239,67,223,57,95,23,12,142,129,6,218,245,239,113,37,29,193,149,237,186,178,250,162,79,148,199,62,83,206,242,219,122,6,140,66,230,57,204,55,185,171,77,174,122,135,53,121,183,159,111,177,52,219,219,89,56,55,110,175,12,150,111,116,224,59,17,64,144,137,159,233,73,14,175,119,107,92,197,155,22,136,37,13,39,71,181,116,136,70,17,163,149,199,53,93,47,74,37,241,162,115,159,59,120,181,16,77,215,148,140,206,187,231,180,220,106,190,118,224,230,131,242,150,93,241,25,240,34,230,131,53,114,150,243,220,9,160,38,226,27,167,215,112,217,237,220,7,111,212,196,157,206,241,24,133,242,121,198,198,247,187,224,239,36,197,234,157,231,217,127,58,148,16,241,36,96,162,37,231,217,195,26,255,145,170,238,91,36,149,22,247,156,22,79,57,75,31,107,7,107,133,185,228,222,193,125,178,28,163,115,19,11,30,161,219,113,167,213,219,207,201,95,101,99,235,93,211,32,211,48,210,140,95,120,187,245,131,217,158,249,19,154,155,87,183,250,31,255,80,251,150,196,161,49,106,62,107,243,38,240,192,65,67,3,70,107,33,71,98,168,254,197,61,91,55,218,190,56,20,217,147,111,94,100,74,224,45,31,187,157,228,171,86,147,21,48,35,145,42,190,251,94,13,227,52,151,218,88,119,216,66,115,149,203,52,113,24,161,12,14,95,114,53,187,78,46,14,236,30,184,244,158,61,144,254,226,170,247,136,110,93,131,12,116,77,232,101,64,125,224,94,72,188,87,171,207,118,227,91,1,123,230,224,14,39,119,38,4,61,121,193,45,30,118,111,154,153,125,122,236,244,125,56,177,179,253,188,114,115,79,107,96,183,123,93,150,1,95,192,165,25,243,209,254,216,185,226,141,61,13,62,221,9,182,109,249,159,94,172,107,174,179,133,126,205,124,58,188,127,226,93,168,64,94,119,34,233,205,122,62,53,43,162,144,141,129,123,209,220,120,118,54,193,178,110,40,87,154,155,185,217,108,111,213,187,185,198,123,113,165,94,159,189,35,73,41,146,221,38,232,55,87,85,207,72,251,79,117,198,60,217,233,124,103,87,76,205,101,149,198,18,231,197,255,3,207,76,223,185,118,129,133,67,17,143,117,205,14,231,173,157,50,93,87,116,217,246,209,17,157,163,11,227,57,234,125,201,155,29,188,35,163,147,15,213,49,11,115,111,65,164,23,35,243,188,230,198,26,220,174,8,135,220,29,204,34,205,165,181,198,148,113,15,222,47,225,247,18,244,220,114,125,8,246,122,43,2,243,246,153,246,224,221,180,204,179,137,181,161,157,73,62,221,95,187,238,197,173,5,219,251,210,50,50,113,199,173,109,54,31,145,209,182,173,187,113,46,39,219,227,139,36,183,195,33,37,205,219,226,129,137,254,95,202,142,103,111,232,109,117,203,42,104,78,16,41,153,216,210,123,212,119,106,151,195,247,83,117,199,42,56,236,90,203,158,133,171,143,84,202,75,246,244,156,198,48,154,156,9,21,8,84,121,98,83,45,124,62,117,161,79,117,111,191,152,123,213,73,220,81,227,59,239,121,252,118,159,98,238,11,10,186,140,9,126,131,188,19,194,44,203,74,212,214,234,188,152,80,79,140,140,73,72,56,93,201,1,158,254,230,252,177,23,178,163,183,235,242,133,19,198,37,81,145,130,193,135,55,184,218,237,120,191,177,131,120,50,130,45,83,203,118,77,141,157,101,208,134,7,85,41,242,146,156,81,50,239,198,158,135,132,246,72,140,245,236,27,97,117,78,106,58,135,237,61,114,182,141,157,240,58,232,68,164,66,26,175,60,143,223,248,192,157,7,173,41,181,230,109,151,181,99,181,140,153,87,103,55,232,68,66,15,221,63,61,121,182,44,175,167,181,43,30,147,249,185,34,144,77,79,254,18,209,218,124,4,69,76,71,12,243,57,155,188,148,150,229,235,134,214,227,43,95,13,214,187,23,106,169,29,9,27,236,236,60,206,86,136,156,126,82,85,194,179,207,167,236,129,239,105,97,155,77,95,242,95,64,147,211,57,63,226,38,163,111,72,63,89,253,150,183,208,114,78,108,90,56,19,186,48,158,83,116,39,112,108,44,54,54,240,192,251,172,111,152,146,13,130,39,92,44,129,221,77,103,109,220,63,205,127,218,17,194,36,91,194,243,116,126,186,127,210,238,83,241,121,222,219,62,193,151,183,97,223,102,57,177,167,163,230,166,71,107,205,250,33,28,39,164,67,102,87,7,134,245,202,159,223,60,186,215,6,242,186,69,42,127,224,198,19,187,53,119,110,216,31,26,27,29,111,194,176,200,165,114,57,136,79,188,178,89,251,245,73,127,230,153,172,88,211,182,99,105,25,140,91,153,45,18,95,146,228,247,52,122,54,185,39,243,200,137,72,127,228,126,188,250,52,207,190,201,254,211,58,1,12,109,6,254,167,50,162,83,170,218,76,45,236,32,62,23,203,120,25,250,248,11,163,180,183,142,97,74,248,188,70,165,89,236,81,247,245,122,179,239,171,74,164,27,15,59,148,222,23,157,236,148,38,109,117,120,140,219,158,22,212,254,166,220,67,86,158,247,52,242,229,241,38,152,221,71,147,118,11,108,178,41,169,242,170,170,229,8,227,84,5,207,62,98,92,153,170,113,116,209,62,17,164,181,63,123,212,43,145,168,85,172,86,87,86,217,172,45,203,197,57,205,165,148,31,132,97,133,56,55,228,206,141,55,37,251,110,182,93,171,119,104,219,180,174,237,90,197,137,133,185,94,51,82,185,68,88,101,22,39,68,152,203,131,99,7,242,253,187,72,45,113,102,115,246,206,90,88,151,106,33,177,247,173,168,225,170,113,78,181,206,75,150,205,159,158,135,20,244,151,245,190,210,100,138,149,56,81,16,112,175,219,180,25,102,38,112,194,163,82,182,228,21,38,79,51,96,58,87,195,179,205,193,118,167,81,119,108,107,73,223,246,129,17,193,91,151,206,38,198,92,80,41,56,197,163,211,37,49,43,24,190,39,219,181,154,169,151,179,246,174,248,184,203,61,175,175,5,218,33,107,242,82,98,142,234,59,231,147,92,99,110,8,142,175,63,124,196,121,0,94,76,56,202,55,206,121,48,230,170,187,143,201,166,246,4,15,70,139,254,154,33,141,246,119,3,239,123,2,228,70,184,115,26,157,194,120,190,42,159,170,11,115,85,43,25,19,31,119,9,14,228,147,67,24,110,12,183,120,240,56,126,212,158,189,57,86,22,126,163,160,101,64,47,253,172,15,252,99,191,233,26,13,200,56,119,246,204,33,119,214,57,191,161,130,137,190,93,61,182,91,35,196,236,139,118,30,53,223,161,115,138,173,94,166,18,186,253,254,208,219,107,218,21,119,231,247,206,126,123,57,103,239,123,1,199,44,77,234,233,61,148,94,111,231,219,155,210,84,192,17,238,187,221,198,60,236,69,212,27,239,2,37,163,241,123,220,35,94,79,146,90,110,230,239,86,77,183,9,112,216,2,75,202,43,106,33,21,229,127,57,43,126,182,213,228,201,170,91,141,7,204,42,71,245,72,135,238,135,212,221,207,61,53,92,49,248,249,3,142,175,112,67,174,119,98,178,68,136,61,144,34,49,55,146,180,144,46,238,70,220,21,169,185,117,62,164,32,238,218,208,222,111,229,122,205,239,228,180,142,239,151,228,213,147,59,181,255,195,105,30,68,161,206,7,21,71,45,146,67,164,91,195,193,11,47,97,122,246,205,193,33,108,27,243,164,193,215,188,227,225,195,14,135,162,165,50,211,206,204,246,143,249,182,158,158,206,58,58,146,157,88,3,62,89,115,183,118,212,76,35,37,28,185,131,129,43,117,15,67,15,251,185,181,207,175,152,178,146,190,67,185,82,37,131,47,57,107,187,11,190,126,235,118,64,235,227,222,136,176,212,189,233,143,239,27,177,21,96,55,143,188,50,56,230,183,161,202,250,190,232,209,38,67,25,2,87,41,107,240,83,165,123,142,184,158,217,17,97,87,23,118,165,248,83,200,173,132,56,187,18,43,251,111,89,15,107,246,171,137,108,36,117,79,117,39,53,64,132,42,155,158,49,39,120,198,94,139,218,192,87,82,149,112,222,155,133,215,117,134,157,247,17,60,132,240,193,109,159,250,45,231,234,68,201,91,173,137,181,6,154,11,179,248,133,131,26,6,147,30,161,38,111,175,151,33,94,195,103,163,231,7,27,48,59,90,26,121,227,239,38,183,151,123,5,204,140,18,229,157,187,188,180,12,167,44,66,103,236,202,71,196,56,131,154,79,142,133,138,49,71,71,2,154,49,12,99,133,235,36,173,54,198,127,126,25,154,207,202,45,133,205,31,186,159,47,63,167,134,106,148,17,78,243,57,155,184,58,231,162,233,93,120,207,100,184,122,108,88,72,84,1,94,129,45,86,94,167,179,97,2,83,56,149,159,239,213,22,144,243,201,186,103,79,236,144,113,77,214,252,170,104,197,105,219,35,30,175,143,79,124,101,33,12,236,109,243,151,63,88,18,55,127,114,112,200,56,198,70,89,49,211,1,225,216,41,181,117,227,113,85,75,124,192,204,56,49,198,193,243,138,142,154,204,189,157,126,237,31,50,222,11,26,223,113,90,85,225,37,83,198,82,40,19,233,194,158,62,247,92,35,191,245,227,187,106,193,133,15,60,150,229,22,126,107,184,121,142,6,140,89,75,230,59,122,154,143,143,123,100,11,95,154,49,46,183,109,59,169,56,185,59,198,74,105,188,191,193,140,127,125,179,180,101,121,177,222,166,163,186,96,113,185,254,165,118,108,196,250,210,108,1,47,117,142,155,123,194,43,182,182,70,206,133,53,87,110,253,236,200,23,216,240,128,41,76,191,150,52,118,53,105,236,226,227,30,222,140,24,102,89,62,33,45,198,71,59,222,30,177,86,76,176,136,55,148,177,226,18,17,10,154,190,109,101,172,106,110,119,58,229,57,201,8,154,92,121,168,58,59,83,108,112,125,233,161,104,100,178,62,112,216,69,171,248,70,73,79,132,86,21,235,39,94,237,169,144,122,210,209,34,238,198,137,162,174,184,180,150,67,31,44,191,204,142,84,55,60,191,94,88,227,19,50,39,242,234,189,249,65,151,67,92,4,222,247,207,91,55,25,13,118,218,30,173,223,218,209,159,85,20,220,188,201,217,91,68,34,199,99,211,122,187,201,7,165,213,234,67,123,148,181,199,85,39,63,65,5,122,152,28,226,158,60,57,90,224,219,199,191,221,187,173,237,229,245,3,35,215,106,110,132,73,221,157,159,90,112,92,189,145,209,192,197,241,226,75,182,192,74,146,153,152,132,239,248,96,111,171,207,68,194,205,6,156,71,21,193,155,89,101,243,125,103,161,17,211,103,206,95,26,37,94,60,189,125,251,234,36,105,166,197,75,79,220,235,27,255,104,127,157,45,180,243,130,202,151,181,117,25,111,239,175,59,35,245,17,246,106,173,215,192,253,146,77,61,182,117,201,85,235,191,190,146,233,228,183,217,241,58,33,118,107,45,187,235,192,231,83,69,165,119,110,172,39,193,86,119,15,216,181,169,201,182,165,48,177,188,205,58,189,142,32,197,255,18,34,148,126,226,138,162,219,227,66,243,116,142,120,66,81,110,41,102,232,102,232,128,95,136,171,244,37,25,224,150,248,77,181,60,57,254,134,133,163,86,55,84,156,24,181,46,190,217,204,237,138,238,101,96,66,144,82,148,231,26,44,170,57,246,124,123,118,195,47,246,230,42,175,119,122,155,121,90,250,123,86,183,39,94,170,254,54,147,145,211,138,43,90,152,27,106,209,152,104,78,6,55,245,9,180,116,247,15,62,49,82,29,159,155,104,83,191,127,210,150,115,53,143,240,231,162,210,157,97,27,143,148,112,216,131,151,46,97,114,219,50,252,148,183,223,200,222,16,18,138,229,45,21,115,24,179,125,147,49,15,47,242,16,240,219,244,218,33,43,177,160,89,29,83,196,91,116,36,166,136,247,224,66,29,168,95,143,188,241,212,233,186,169,101,41,34,146,114,148,81,224,98,248,26,18,165,169,170,146,102,160,108,49,125,165,126,35,99,205,188,246,140,114,133,212,8,211,190,207,37,175,57,196,43,246,189,202,173,139,214,106,12,14,237,178,46,126,100,34,30,235,216,167,55,206,255,246,124,21,108,127,143,52,105,42,108,102,36,37,230,201,204,96,190,89,85,209,43,23,195,146,130,7,47,108,213,23,190,40,119,78,204,182,116,123,61,40,186,210,201,207,29,133,221,241,0,123,109,235,208,7,204,85,123,149,198,142,233,67,91,207,29,182,169,220,0,75,70,125,48,51,84,127,40,51,195,43,159,63,209,68,42,58,222,153,148,205,173,183,47,181,53,133,43,71,209,223,231,125,205,167,130,78,103,163,171,178,253,106,89,236,200,16,215,91,85,183,170,221,158,108,25,66,113,159,46,76,225,106,115,120,108,249,118,188,177,74,125,232,169,233,56,209,200,223,35,92,99,28,171,254,245,97,84,200,29,217,216,23,151,52,162,155,119,197,204,218,153,228,62,55,190,181,55,34,147,111,128,181,176,39,71,162,129,24,164,238,217,54,42,85,73,220,153,158,43,207,23,118,225,88,250,113,171,57,223,244,158,6,144,165,220,177,174,14,29,101,162,228,113,168,44,196,239,46,116,162,73,26,118,92,39,53,173,61,176,61,167,183,77,164,173,157,131,152,189,221,241,218,59,181,150,118,109,216,39,166,233,76,219,172,163,223,237,223,13,105,202,1,19,131,126,67,253,119,183,165,223,61,246,64,103,210,132,239,193,52,106,10,105,16,22,50,103,90,238,146,206,184,109,7,211,25,75,232,213,190,226,1,245,226,175,121,221,137,199,106,234,108,180,119,173,159,78,45,18,97,170,97,62,192,47,162,220,198,121,219,238,129,179,106,169,196,236,1,191,234,24,151,3,155,91,227,93,90,61,239,41,113,224,8,231,114,9,217,205,221,107,25,146,227,172,25,83,185,30,223,224,200,222,70,44,14,99,54,4,120,153,117,207,119,60,109,16,228,221,190,53,236,141,96,144,239,230,14,46,13,126,130,16,231,134,82,109,141,61,35,76,251,102,83,119,122,124,97,101,189,4,112,30,139,183,224,147,218,117,244,77,165,36,193,213,233,211,106,146,75,2,49,186,137,180,48,87,247,244,205,88,3,180,45,123,34,252,177,80,88,242,118,98,208,198,182,26,241,3,146,143,46,197,249,71,153,212,174,51,158,188,185,103,80,170,112,210,73,185,186,121,68,229,131,136,253,68,240,183,164,218,130,16,230,60,129,91,164,193,189,97,35,22,19,179,51,70,83,44,181,42,141,188,59,178,216,197,111,155,43,15,219,90,118,42,74,158,243,10,92,219,168,28,122,44,47,161,91,120,252,107,152,168,77,178,208,149,251,10,109,50,223,28,167,121,152,228,182,60,205,155,29,174,216,62,218,255,206,64,192,61,60,197,179,57,4,126,88,158,101,154,135,61,164,161,81,60,67,49,244,178,228,72,165,124,142,95,207,245,208,27,218,222,126,221,33,28,8,61,231,227,226,151,99,82,134,115,223,23,156,112,44,207,223,88,187,48,127,160,229,9,17,31,176,169,175,189,53,112,198,125,1,247,92,117,248,142,75,245,234,247,175,142,62,63,143,35,1,179,236,158,161,174,129,144,247,42,73,55,113,165,55,118,197,223,232,115,124,59,63,243,117,104,126,178,100,239,71,80,35,112,230,107,206,177,11,60,51,147,83,153,130,223,207,149,100,20,149,126,8,21,8,72,157,177,250,0,92,18,176,185,131,151,25,18,244,147,82,60,46,143,78,41,188,162,255,233,153,130,115,68,80,143,148,74,212,187,111,155,23,40,61,237,97,86,133,180,200,97,232,167,40,33,243,213,140,98,49,118,80,118,139,213,236,108,59,133,28,199,174,166,247,167,93,48,145,78,223,143,134,235,187,90,51,58,1,66,17,126,140,183,188,135,163,57,99,189,190,155,60,218,49,223,184,119,109,124,76,251,76,146,146,251,225,3,23,101,196,189,77,239,31,123,141,250,106,145,102,78,192,172,254,190,78,60,252,226,246,241,125,207,6,124,84,6,66,101,230,218,123,229,56,31,122,191,115,228,28,132,71,136,12,190,61,19,189,41,208,91,122,94,191,98,232,161,255,203,49,51,205,43,87,92,215,220,233,252,138,74,234,173,12,40,147,226,219,82,238,105,181,53,95,109,167,99,154,242,189,139,201,86,44,94,124,187,62,72,138,36,180,8,144,102,61,222,125,234,31,237,173,13,27,21,183,81,219,87,244,66,123,98,42,243,253,39,247,251,93,235,219,78,4,126,253,152,146,150,63,55,222,196,55,238,103,132,83,110,245,78,158,153,238,207,178,46,122,19,225,45,117,255,21,151,94,136,182,247,208,16,105,193,239,221,17,160,99,199,11,211,138,10,243,146,221,182,155,94,250,25,201,222,109,126,148,224,245,209,78,24,112,124,38,62,216,234,211,205,55,81,56,96,157,51,144,93,81,140,185,60,167,158,81,41,210,196,52,244,60,23,58,173,190,53,101,112,243,137,115,207,248,73,30,19,61,201,225,187,187,2,124,203,182,76,92,159,244,106,200,132,201,191,30,14,40,149,14,12,142,148,113,248,108,51,75,16,169,176,185,48,51,17,185,219,159,23,121,171,119,214,165,255,243,211,13,99,80,141,14,251,228,155,59,244,10,20,246,15,95,49,229,2,130,217,57,79,55,216,169,125,226,129,238,10,126,35,28,81,111,222,55,27,209,3,47,102,213,253,90,125,206,214,23,39,3,156,176,211,221,90,237,174,31,206,124,204,16,24,226,17,100,99,150,204,235,184,136,46,24,171,175,45,240,241,191,52,209,234,151,21,184,48,175,255,161,192,119,204,19,74,26,179,254,194,207,208,248,80,178,138,207,179,17,166,230,136,47,23,189,189,177,170,57,208,76,173,91,6,31,24,178,94,9,155,85,48,30,23,55,253,60,113,109,163,248,231,177,6,168,244,183,225,135,181,166,248,106,205,145,115,71,31,152,138,205,62,243,57,60,249,185,96,116,107,100,225,222,64,199,70,233,207,97,210,243,14,245,231,252,22,10,140,19,189,202,188,145,177,70,174,231,172,252,88,117,125,15,90,237,251,56,81,119,180,232,193,116,235,177,180,140,91,76,82,150,183,77,207,223,88,59,119,54,56,102,76,249,80,91,85,34,223,96,21,92,217,164,104,158,49,97,160,42,243,246,192,131,225,203,61,13,147,171,10,90,164,183,221,65,22,50,112,59,168,207,123,26,176,56,168,5,206,78,70,151,196,87,223,179,125,151,153,63,216,167,31,206,159,49,205,227,87,34,212,219,64,249,218,0,211,220,54,203,78,53,7,57,219,211,171,86,109,218,107,164,171,109,101,184,75,236,166,232,107,227,195,246,99,210,107,164,7,11,103,208,45,213,169,34,217,224,81,145,93,182,126,67,5,57,211,184,201,207,161,253,119,183,142,12,151,8,144,8,240,206,143,102,123,231,58,6,182,230,55,68,183,123,54,185,119,127,107,56,24,58,77,220,195,55,253,245,213,164,189,202,33,214,53,38,236,158,133,47,111,178,199,30,60,25,86,168,49,196,192,86,185,219,97,130,223,104,79,66,237,158,169,151,107,68,15,94,240,186,92,38,32,82,34,123,175,75,93,188,164,33,102,238,164,249,133,25,118,191,35,1,83,157,49,232,158,183,215,231,59,159,104,132,31,18,238,192,180,236,142,99,173,216,195,208,19,247,240,140,229,149,240,61,130,134,140,66,17,172,140,135,93,144,104,11,125,208,97,183,83,177,97,196,170,195,70,85,47,140,182,172,55,91,245,100,255,132,156,41,210,18,92,109,206,110,92,108,55,193,180,55,51,125,237,250,246,72,73,198,131,175,69,218,203,119,159,223,54,62,160,93,82,159,145,211,218,167,212,140,213,81,246,159,196,38,40,94,96,87,175,84,130,230,66,247,122,125,123,206,98,144,181,208,165,252,178,197,210,108,111,175,103,35,140,37,103,110,188,201,205,133,87,109,235,59,152,149,211,30,195,9,85,45,151,154,188,238,196,52,38,9,65,131,11,4,166,53,108,216,158,61,5,102,107,18,53,19,101,117,170,118,219,117,139,168,73,75,95,214,56,167,212,68,176,204,169,171,183,239,175,252,82,194,239,87,185,227,104,254,224,227,248,124,237,74,137,41,158,119,22,159,155,240,74,110,202,251,141,71,206,180,132,67,75,6,112,174,154,108,86,157,117,200,208,100,221,86,181,209,225,56,246,98,245,80,230,111,223,13,77,36,190,206,148,195,206,238,215,223,58,61,50,90,91,109,206,247,168,92,44,173,231,65,100,224,92,127,6,186,253,188,178,103,209,252,88,150,117,145,19,207,234,81,183,162,216,192,22,223,254,140,230,90,179,189,41,51,175,38,167,31,145,22,230,171,96,240,58,79,92,192,64,71,148,153,13,55,246,118,82,224,147,201,239,15,155,172,8,194,149,167,119,164,135,10,248,28,154,88,59,253,82,96,254,218,208,208,211,10,169,99,236,27,171,81,143,234,108,182,113,244,52,136,14,15,160,111,64,179,138,62,79,31,127,120,44,214,162,120,245,243,171,199,251,199,147,51,166,189,178,10,38,112,152,162,177,199,126,11,115,19,196,125,199,167,162,8,254,189,41,49,219,141,83,174,188,60,170,0,124,155,108,55,211,77,75,7,224,50,249,161,114,171,209,175,121,108,9,6,124,196,75,177,154,26,246,44,59,60,35,71,95,8,137,197,46,180,11,44,96,117,26,182,244,233,159,223,150,82,253,184,59,73,135,67,227,161,70,22,79,81,84,196,229,195,166,187,142,148,84,52,161,243,51,120,73,53,222,19,182,162,89,202,77,40,252,149,210,251,153,236,252,173,30,37,124,131,182,69,211,151,103,134,72,243,241,79,114,44,226,154,111,50,167,120,172,31,50,26,121,98,215,181,134,131,127,128,125,110,110,168,197,199,226,66,214,227,143,125,232,142,82,141,75,83,235,164,159,126,26,140,153,91,179,55,81,214,178,170,226,176,42,154,149,221,118,76,73,149,109,147,226,57,166,167,107,106,72,235,163,178,84,77,69,70,111,198,69,72,140,189,235,86,9,56,167,198,26,161,117,121,173,194,68,246,225,150,107,251,175,203,109,225,114,189,172,245,177,227,147,13,180,131,137,104,112,45,101,97,71,211,229,196,74,142,181,218,239,210,222,132,155,109,206,80,143,132,29,55,188,198,196,28,39,174,207,247,237,250,173,44,39,142,176,215,155,236,43,77,226,20,202,18,176,47,88,171,60,144,23,131,227,235,154,85,187,175,90,222,59,51,53,152,63,148,25,162,226,61,126,231,118,34,174,49,235,153,218,70,191,241,193,148,162,90,46,166,34,155,163,62,96,130,131,255,187,147,155,159,8,144,226,218,187,134,222,181,172,183,135,199,170,235,57,223,26,122,212,112,244,93,218,22,149,23,107,186,99,202,248,121,27,205,82,195,98,51,237,136,151,173,91,170,148,219,210,31,228,15,61,233,207,60,62,39,112,47,88,229,69,168,232,173,220,151,133,219,10,16,93,5,238,79,249,139,194,189,252,42,202,111,231,234,28,42,216,52,240,181,222,206,37,97,50,163,121,86,127,47,127,177,152,29,178,218,36,186,206,76,151,24,113,100,225,78,146,194,101,195,178,143,110,89,146,105,24,223,242,68,45,229,220,182,3,183,243,242,250,51,243,223,192,86,87,223,52,242,202,231,54,219,115,80,58,249,216,147,187,132,212,36,63,244,245,192,215,142,108,106,13,67,133,51,137,230,69,82,156,125,13,243,115,51,105,232,147,153,251,121,27,249,85,176,215,94,126,42,139,149,157,201,11,21,8,20,145,203,80,117,125,11,40,31,171,62,56,120,51,202,244,172,241,171,4,210,252,212,93,168,116,209,23,220,135,176,46,179,99,22,184,203,214,182,30,202,173,132,168,62,219,87,60,126,223,99,45,249,196,96,94,67,173,45,82,60,219,55,72,247,236,143,221,118,62,95,104,174,233,246,196,241,193,145,163,80,161,190,254,201,153,198,218,158,232,162,102,46,177,236,174,248,117,163,3,162,51,138,1,245,168,39,108,76,155,76,43,56,120,57,95,192,93,18,125,110,177,19,28,60,63,128,22,133,87,119,114,111,138,107,62,30,176,233,61,43,187,75,82,128,167,211,145,118,152,237,176,242,161,227,188,227,209,195,124,229,247,142,106,248,9,71,167,84,72,60,56,151,63,114,65,189,69,155,133,175,131,223,251,19,102,80,123,170,191,214,107,71,206,235,77,241,253,215,182,174,217,37,203,250,204,171,177,159,165,19,122,172,213,240,232,205,203,231,53,16,73,41,173,22,153,211,157,44,229,30,108,185,48,197,15,39,55,31,249,20,120,209,90,87,195,183,50,139,9,115,187,204,177,35,209,111,176,151,37,171,91,249,204,17,201,198,252,28,123,175,22,98,216,96,221,215,147,107,106,73,196,248,112,226,37,153,153,11,7,76,90,239,38,119,200,137,10,105,49,242,0,156,158,217,183,134,144,118,193,64,239,46,214,135,251,1,137,182,155,178,156,89,204,57,211,187,5,82,189,24,119,242,172,254,26,155,158,146,99,116,233,88,122,111,116,134,200,141,119,19,195,226,210,249,196,6,59,229,143,109,130,246,178,8,148,225,181,199,204,50,246,31,148,60,138,207,33,8,251,58,63,92,31,249,154,63,84,88,123,225,229,67,211,157,55,135,102,134,138,26,186,125,15,8,155,249,109,119,206,124,89,89,85,115,64,58,161,241,32,24,248,226,21,71,165,240,216,37,246,103,227,167,192,192,71,157,167,3,20,28,139,7,115,219,47,212,50,164,63,126,26,159,226,34,187,110,190,47,45,171,158,189,40,183,236,174,196,235,40,143,59,210,140,220,194,166,4,245,161,167,15,118,67,196,173,182,165,8,122,55,231,122,12,142,202,155,198,212,113,77,84,64,46,84,157,149,123,116,120,154,135,65,80,162,231,155,102,192,244,198,215,47,165,158,17,182,37,166,61,14,124,244,45,141,56,59,59,82,157,140,203,56,12,179,81,219,30,187,105,118,180,214,140,111,205,153,244,228,156,26,88,241,156,129,234,5,141,108,25,206,24,133,79,39,186,51,36,52,230,39,219,249,108,238,43,30,143,223,33,158,184,217,129,112,208,68,172,230,220,195,218,72,173,12,86,199,23,155,119,67,141,186,67,102,70,31,84,239,143,94,255,232,130,248,75,97,6,174,210,221,12,198,223,38,91,50,139,44,211,128,112,141,249,92,123,183,140,71,217,91,15,22,223,189,190,182,217,167,59,1,29,239,158,243,174,12,206,177,231,91,208,248,103,133,141,171,118,63,62,189,170,210,58,235,222,11,136,239,220,197,3,82,103,210,247,111,212,56,212,190,238,181,229,7,183,237,215,95,125,2,75,33,130,110,4,33,45,198,49,179,85,51,14,151,218,29,3,89,72,95,137,61,169,18,46,150,152,202,232,226,129,201,99,234,149,129,250,219,57,84,59,34,142,177,180,76,125,134,77,239,225,99,181,138,12,170,122,127,81,177,216,154,237,209,184,246,243,167,93,204,118,1,76,115,145,10,128,149,228,28,132,171,243,196,73,211,217,195,61,13,199,186,173,238,104,223,63,86,146,242,224,197,75,128,127,254,88,175,185,190,19,120,88,212,235,238,192,76,104,157,249,161,186,247,34,153,7,199,160,201,29,152,204,90,209,16,109,145,203,110,138,167,175,186,121,158,219,195,26,161,149,170,174,123,198,60,220,124,75,182,238,51,99,91,101,155,52,249,3,170,17,45,185,136,130,205,233,7,60,223,241,20,163,76,31,111,150,227,209,143,46,50,188,182,134,57,59,19,117,44,72,40,71,219,73,175,42,57,74,192,154,251,64,192,204,120,149,187,26,167,135,196,190,215,168,183,231,164,245,171,20,225,250,154,231,181,26,191,191,55,204,206,249,246,98,93,62,247,43,137,237,227,237,121,95,206,138,215,60,251,166,198,170,192,28,156,150,249,164,220,36,176,99,131,114,224,172,119,11,203,189,29,92,124,187,178,191,143,66,47,17,18,35,168,143,178,118,49,20,153,14,37,53,128,78,87,82,155,57,131,84,221,217,215,116,238,206,191,203,117,176,214,204,46,38,236,42,219,218,71,40,17,251,203,205,112,64,40,66,135,241,222,173,138,173,94,170,149,185,135,46,193,230,187,238,189,100,199,167,85,204,243,207,107,2,247,75,112,35,220,114,87,198,142,203,40,203,108,125,231,185,193,85,161,96,237,220,253,190,187,105,79,238,195,75,238,218,85,122,106,183,31,16,138,192,51,138,28,224,216,59,139,205,249,216,55,118,48,250,177,178,250,54,147,133,71,49,220,109,105,252,12,166,142,105,252,110,167,116,25,199,244,159,73,215,206,142,248,30,16,174,141,146,102,172,159,170,30,150,132,78,217,148,53,198,5,30,55,142,245,183,146,123,58,62,157,16,197,176,3,189,189,161,149,173,203,111,204,76,139,231,92,180,230,145,147,7,57,242,230,62,186,101,229,105,140,55,190,116,192,87,41,222,241,219,217,33,150,144,190,181,83,44,191,79,60,123,139,16,102,79,173,2,190,74,49,38,127,252,163,91,75,105,164,32,223,40,43,31,171,194,206,96,100,237,45,164,221,89,204,14,119,210,245,233,174,154,216,233,172,194,17,133,182,59,58,221,107,231,219,133,174,251,119,11,194,205,24,31,9,113,142,251,157,56,95,33,225,149,93,127,113,195,203,76,77,134,254,89,131,41,231,238,186,240,213,58,149,92,12,81,76,165,204,54,17,96,29,72,226,216,209,227,55,149,92,150,155,126,150,179,221,218,141,241,174,35,163,191,8,202,169,78,77,90,77,112,214,68,233,195,171,207,89,232,171,103,83,74,133,171,2,235,77,162,187,132,119,236,244,159,44,98,0,151,238,59,153,217,200,222,18,122,91,198,172,212,234,13,15,45,42,38,158,79,91,216,166,92,253,32,1,119,233,245,245,29,47,81,37,81,247,5,25,184,74,85,130,187,124,11,136,185,206,123,30,159,59,202,196,249,173,41,110,222,135,73,40,193,200,120,199,42,213,123,252,31,37,42,116,61,67,239,178,73,168,113,119,134,67,218,130,190,25,50,158,100,222,183,58,36,252,230,55,53,82,164,150,231,218,84,174,106,83,194,150,168,83,59,130,196,152,249,40,135,255,157,12,125,69,250,149,99,219,111,218,125,20,71,53,116,3,73,91,244,200,76,36,188,178,157,183,243,37,219,50,48,214,243,24,228,165,175,106,190,234,123,37,212,215,123,156,229,196,64,69,249,29,78,153,143,66,230,146,140,179,86,119,245,226,62,63,12,93,37,110,240,245,122,177,151,154,105,80,220,253,118,182,94,38,214,8,45,77,86,243,133,78,249,182,190,61,245,53,58,47,212,96,9,221,178,81,6,140,60,187,0,144,23,181,175,54,82,235,212,218,212,231,252,87,174,87,177,114,108,45,223,168,159,98,205,248,65,128,243,24,191,13,252,245,253,186,167,29,76,235,247,63,43,60,191,230,225,217,247,215,84,19,179,16,241,254,217,31,19,179,252,211,146,26,203,113,238,74,219,250,133,213,175,112,113,1,193,74,156,215,230,221,152,36,52,15,235,49,74,196,164,173,141,215,142,212,74,216,240,54,161,180,241,251,65,151,188,184,161,14,87,82,232,168,61,62,230,169,127,55,220,165,152,127,236,234,158,81,18,121,137,58,206,154,50,150,50,189,121,179,113,199,180,30,99,231,6,199,228,187,123,76,253,239,42,49,91,105,234,5,132,218,88,185,113,179,156,250,152,202,124,8,227,250,254,170,203,19,163,32,230,212,5,17,38,187,93,128,131,243,64,101,213,177,46,153,163,66,17,62,140,177,210,111,184,164,70,62,188,55,223,240,112,94,165,116,119,69,206,169,242,233,139,103,220,63,232,165,118,192,21,11,174,132,51,236,112,216,165,251,8,106,105,4,251,36,164,197,40,244,214,148,209,36,86,86,135,167,213,212,215,63,99,142,249,225,240,179,179,62,51,12,195,38,92,64,112,51,215,181,249,10,247,250,58,228,43,123,181,178,92,92,134,233,131,216,178,157,193,125,156,17,74,224,161,23,214,194,42,167,246,49,102,108,184,199,176,99,79,119,82,206,56,255,80,131,116,240,189,55,81,115,79,188,199,77,138,245,228,246,61,18,184,254,137,149,213,155,249,198,190,80,190,65,126,158,68,231,51,90,169,5,162,215,236,202,163,124,195,15,220,220,188,235,186,100,130,249,88,226,177,91,225,204,134,65,204,16,117,193,212,5,145,13,118,59,222,166,28,104,252,26,244,17,232,148,19,207,123,225,29,161,197,206,106,248,146,43,106,125,175,33,32,206,220,85,121,133,91,255,100,11,159,93,217,197,184,18,193,244,238,19,140,176,177,164,56,3,177,29,140,87,4,56,33,132,217,36,186,155,102,187,212,63,76,37,92,123,165,195,104,7,112,150,185,108,218,249,82,69,129,141,122,219,204,45,150,13,182,207,40,136,249,174,126,208,116,214,177,212,173,230,188,107,83,143,236,143,74,220,125,162,105,213,249,240,139,171,88,55,114,222,27,62,239,123,115,213,58,210,251,216,160,177,231,39,109,14,54,122,57,180,15,148,234,126,11,92,8,233,205,48,214,149,216,116,102,247,153,35,183,74,26,242,137,253,93,133,11,243,126,231,149,52,37,207,75,160,56,244,238,71,71,245,232,75,16,39,237,250,142,190,104,151,140,57,11,61,151,41,227,63,124,123,86,145,36,54,59,191,191,47,214,16,249,208,53,122,248,13,121,220,124,129,250,63,17,134,62,104,31,116,195,9,67,129,87,251,99,82,223,158,118,192,140,185,124,15,123,199,19,189,151,31,19,72,154,157,159,156,59,184,112,83,228,189,33,242,86,179,89,193,145,89,39,194,201,233,152,105,101,177,33,187,249,123,179,176,169,151,195,194,41,192,25,200,249,75,51,119,98,194,160,231,50,239,205,246,154,79,61,168,53,85,207,139,199,20,170,94,246,151,196,32,2,79,154,175,219,254,33,200,34,80,75,4,76,200,219,254,61,109,10,194,142,52,29,234,181,175,146,158,233,254,124,160,202,182,195,192,123,211,60,239,196,165,207,202,181,187,73,229,2,69,123,251,4,222,197,84,109,219,145,41,22,224,144,62,225,159,208,159,100,185,112,92,75,62,178,231,92,39,71,234,171,147,103,59,49,35,13,197,195,49,157,210,21,208,232,162,42,53,139,253,97,185,119,79,76,43,148,12,219,26,78,18,217,23,246,156,120,239,191,203,87,106,150,47,180,124,56,180,211,236,129,208,125,138,156,6,163,224,3,253,211,105,229,230,25,167,22,250,52,160,221,211,221,159,5,223,23,173,145,16,218,48,207,27,90,62,124,219,238,99,227,60,108,42,170,127,184,196,38,226,131,109,82,74,123,117,246,198,43,55,115,211,243,7,159,160,187,42,175,100,186,84,39,162,83,46,219,88,68,29,122,156,202,106,240,236,181,192,128,210,244,181,175,252,179,163,213,146,108,11,113,9,237,1,234,37,178,189,14,126,197,69,37,223,202,138,162,135,67,239,221,54,190,114,99,184,232,21,215,129,39,12,76,211,6,184,129,10,209,55,85,87,174,182,231,36,196,163,154,222,21,185,12,237,106,73,158,181,156,63,80,182,192,155,85,52,232,28,56,124,230,101,246,7,98,189,157,129,94,25,226,77,140,108,148,164,250,244,132,8,105,71,176,144,210,236,252,197,162,162,106,205,153,74,147,120,37,19,94,78,241,140,167,217,245,59,140,47,136,144,96,45,101,11,197,198,143,7,122,218,228,209,70,19,34,164,178,97,22,41,35,182,246,6,227,77,231,51,248,218,171,63,123,213,104,28,17,79,33,85,145,158,98,222,20,57,119,119,229,240,125,79,111,121,48,113,113,80,118,22,53,188,240,57,84,160,217,210,76,35,101,58,107,33,136,1,93,182,43,230,33,74,162,212,182,2,94,97,175,46,183,32,186,176,155,119,183,138,81,246,187,250,161,133,185,137,54,175,161,130,137,196,190,236,71,245,135,43,136,95,63,90,87,87,97,212,45,230,69,72,151,35,138,114,143,216,109,217,237,229,121,110,111,104,155,209,4,246,124,39,102,108,166,237,173,244,100,49,47,198,53,49,61,247,203,217,140,250,161,72,82,151,68,245,247,166,55,146,152,175,61,109,20,246,11,162,11,243,19,11,83,221,73,249,182,71,125,244,58,113,39,121,108,176,5,190,99,53,248,168,235,185,71,14,206,31,158,254,126,126,245,5,15,211,201,132,134,161,161,38,76,17,177,90,99,226,170,169,201,97,76,193,152,130,187,221,172,240,200,238,246,236,181,231,61,118,50,112,1,191,255,47,120,207,134,210,200,178,220,61,48,240,136,81,16,121,155,255,238,63,64,157,89,5,184,148,240,212,209,248,111,0,131,152,13,175,237,100,86,1,172,54,164,143,94,250,59,200,32,230,108,157,32,166,125,31,202,214,21,159,248,123,88,177,125,65,76,251,120,158,239,55,251,87,220,127,197,253,87,220,127,197,253,87,220,255,129,226,206,11,60,235,139,56,252,176,199,70,97,213,170,85,171,140,244,76,117,51,247,57,30,95,245,203,23,158,232,228,142,65,16,81,32,94,154,128,195,194,37,177,56,12,1,3,199,160,164,17,24,56,94,122,241,19,20,1,226,145,46,104,41,119,196,175,169,252,254,37,35,35,35,163,164,160,64,249,87,70,70,230,135,127,229,229,228,148,20,87,201,42,40,202,202,200,42,202,41,201,42,173,146,145,147,83,148,147,91,5,200,252,71,152,253,211,23,17,79,128,225,86,201,200,224,48,24,194,239,224,254,110,254,71,229,254,151,188,236,173,204,116,28,32,16,65,64,7,134,133,57,33,81,72,2,18,196,3,48,52,2,208,5,221,97,104,4,30,2,241,7,86,78,250,211,102,0,0,240,135,248,3,146,116,47,224,199,143,100,100,11,115,29,86,127,0,7,186,99,8,32,128,68,19,64,156,51,12,14,2,112,24,10,5,160,144,110,32,128,194,192,97,168,31,103,40,168,150,4,28,8,115,7,252,1,130,43,8,44,58,35,128,119,197,16,81,8,192,9,4,96,78,40,16,32,96,0,60,6,229,9,46,2,57,161,64,119,0,227,12,16,112,48,52,222,29,73,32,32,209,46,0,10,134,115,1,1,4,140,0,3,176,48,184,27,72,160,42,233,14,130,4,10,30,30,14,162,97,56,36,134,140,136,167,112,37,99,81,224,105,116,240,120,36,6,45,69,213,25,48,68,186,184,2,230,32,206,25,131,115,135,161,225,32,235,143,50,82,55,12,133,7,210,29,139,2,221,65,52,1,70,64,98,208,0,26,4,17,100,153,225,24,52,30,137,0,113,0,118,153,12,128,196,227,137,32,158,194,66,7,227,142,133,17,144,20,179,251,0,187,1,75,56,12,69,93,4,31,214,63,102,70,51,149,43,204,19,4,156,49,56,47,24,14,1,192,87,16,38,35,225,151,73,211,236,78,196,98,49,56,2,96,66,68,17,144,88,20,8,88,130,56,36,12,133,244,165,82,253,53,123,26,47,60,13,215,125,17,23,191,2,215,29,36,184,98,16,120,9,0,79,132,187,2,48,60,149,140,19,209,89,2,216,111,105,102,42,1,128,4,184,212,74,41,150,40,233,130,100,217,113,32,101,41,0,127,224,31,137,129,88,129,76,19,67,10,240,7,40,62,10,122,16,65,60,1,176,66,186,131,24,34,1,208,193,160,9,56,12,138,21,0,252,1,171,95,248,30,22,135,241,68,34,168,46,183,104,57,234,154,146,209,0,28,141,28,129,70,142,170,143,57,12,143,39,123,149,21,14,6,39,255,107,132,166,172,59,205,164,255,132,15,22,134,199,147,253,146,66,6,73,79,134,158,143,54,145,224,250,159,101,2,35,211,248,75,14,186,62,224,255,1,69,16,84,42,127,201,69,135,136,39,96,220,129,125,68,60,18,13,226,241,244,236,88,255,35,252,224,84,122,78,139,244,86,50,134,8,2,186,84,79,210,70,35,0,163,21,251,9,2,17,20,4,204,23,89,81,193,32,144,29,246,128,48,210,29,230,2,74,97,209,46,194,14,34,212,220,73,25,249,33,171,146,1,68,33,16,103,12,14,32,162,97,56,31,114,108,20,193,160,65,73,154,195,72,82,223,227,177,24,52,30,20,149,160,72,15,162,9,72,220,138,208,5,104,0,250,72,111,192,16,132,33,64,220,208,211,211,178,74,128,147,15,1,196,15,61,61,35,14,88,83,232,82,231,128,197,143,251,48,8,31,41,42,95,106,112,35,51,254,15,145,167,69,100,125,28,204,29,20,49,66,35,9,210,186,48,2,76,90,31,4,157,96,112,55,105,29,99,12,30,20,5,32,16,50,105,242,126,67,129,132,21,91,212,25,137,70,146,45,41,1,96,81,32,12,79,142,14,32,96,79,54,146,20,5,202,65,132,98,49,233,229,17,209,31,141,78,128,33,81,120,136,160,160,32,89,76,16,65,19,20,34,73,241,3,103,36,14,79,0,228,168,18,171,65,0,186,65,130,23,134,58,76,73,14,244,62,3,195,129,128,59,204,5,9,7,208,68,119,39,16,135,151,0,144,104,4,18,14,163,164,14,74,122,32,192,112,132,69,60,178,108,128,51,217,2,18,128,151,43,18,238,10,32,241,128,140,183,170,188,140,20,132,38,134,60,14,65,225,165,70,65,160,24,151,130,0,16,124,176,224,18,127,138,185,33,16,71,71,199,197,32,8,145,150,6,172,188,48,20,48,60,69,46,56,17,135,3,209,4,148,207,98,68,3,17,106,100,40,89,41,10,163,31,73,47,185,150,8,189,43,173,244,43,50,186,220,95,163,83,61,4,2,162,137,238,128,21,14,11,39,47,48,101,189,173,200,16,126,16,43,11,115,29,168,181,169,182,133,29,84,223,66,219,68,15,208,0,100,188,101,100,212,33,212,25,75,43,11,61,109,19,250,41,89,117,72,0,89,201,69,227,40,16,92,105,198,89,206,180,203,50,72,0,24,52,202,7,240,132,161,144,8,192,203,21,68,255,210,132,72,60,224,248,19,59,199,159,108,169,143,33,226,254,192,152,142,70,166,70,86,142,84,250,106,128,190,209,33,67,61,109,93,61,11,64,156,98,0,170,207,147,157,221,4,36,192,40,240,186,218,86,218,191,132,119,194,32,124,0,145,165,208,178,152,251,64,4,69,3,138,233,29,245,245,244,116,247,105,235,28,248,27,134,250,32,136,216,7,131,187,145,153,2,34,4,28,210,197,5,196,129,8,178,209,96,4,208,197,71,13,112,69,186,184,74,163,48,94,128,23,140,0,226,0,20,232,9,162,40,9,157,156,119,112,84,102,58,198,102,150,122,127,195,73,7,133,193,131,20,221,150,22,157,38,194,47,151,253,55,11,14,37,27,114,105,213,127,49,79,54,28,117,94,238,151,243,139,182,161,194,200,255,18,134,162,18,21,64,225,7,215,82,148,84,161,238,113,106,112,35,96,8,48,20,128,71,250,254,180,231,244,233,247,9,176,184,53,0,250,15,228,248,75,193,167,248,30,133,136,6,224,76,9,57,174,212,240,74,25,19,255,225,19,197,3,200,239,169,76,168,46,254,167,164,104,209,153,234,232,84,34,84,197,84,37,101,101,168,154,253,169,236,116,132,87,74,130,7,9,128,204,34,93,89,89,73,89,133,127,70,152,136,70,122,16,65,73,36,226,7,178,148,127,41,195,75,111,41,197,46,158,156,120,157,64,26,30,128,68,3,100,19,160,93,80,228,12,129,70,131,112,106,102,165,201,163,72,17,134,186,124,158,32,142,82,172,81,138,121,44,124,41,96,47,1,43,209,128,113,32,30,196,121,130,8,192,25,9,162,16,16,74,114,32,3,208,210,32,198,153,154,7,33,16,109,103,242,70,89,204,104,18,127,20,46,37,0,36,1,128,99,112,212,1,170,58,100,233,92,151,136,211,39,19,186,148,128,64,146,75,16,4,249,100,131,89,42,9,105,88,228,93,186,100,96,234,152,20,85,238,197,82,148,150,214,126,202,14,174,224,143,180,150,148,128,184,131,120,60,204,5,92,164,177,148,52,253,32,0,64,195,165,179,233,146,57,151,38,241,88,16,142,116,70,194,201,209,151,8,254,168,180,35,57,48,80,104,218,80,137,56,66,0,128,136,68,19,228,229,0,0,88,162,252,171,151,6,64,14,7,20,62,58,228,211,29,57,36,83,63,130,46,106,84,225,201,113,31,148,244,130,249,252,35,113,200,212,200,1,106,165,40,228,19,36,148,146,39,126,37,138,220,162,40,100,30,139,94,137,88,92,72,154,113,69,48,212,196,67,117,81,36,1,131,22,93,193,130,6,6,69,34,126,197,66,158,158,197,226,41,224,7,6,238,248,149,20,151,14,11,191,20,90,129,222,126,32,14,64,195,220,193,159,45,69,45,98,169,229,172,26,101,211,72,193,176,88,20,109,2,74,70,146,162,108,21,28,245,61,197,5,160,228,17,36,28,164,12,73,0,10,0,30,116,33,151,188,120,8,64,43,152,22,109,10,226,126,41,29,160,1,40,174,16,15,252,47,19,207,94,106,169,79,64,249,236,240,179,140,191,90,116,138,140,74,139,50,26,45,181,26,200,36,200,235,66,69,252,59,129,165,201,217,131,92,231,211,75,36,189,82,160,21,242,56,19,209,240,95,75,67,150,71,153,222,73,22,183,46,125,129,72,233,60,96,97,228,146,101,69,23,130,254,196,66,165,176,120,152,166,157,9,37,22,207,84,110,160,143,4,224,130,131,249,72,80,78,114,228,98,159,170,147,4,245,96,44,9,162,61,145,56,12,154,188,220,212,204,64,245,1,242,33,252,31,237,67,19,170,248,63,111,69,154,94,191,220,141,26,128,10,189,9,232,207,97,110,160,143,36,149,27,22,134,196,209,91,2,229,179,220,217,1,201,85,54,197,84,148,140,233,133,193,185,209,188,112,169,208,91,17,132,201,71,0,44,12,71,160,156,12,200,69,52,229,19,57,86,19,126,224,79,77,89,127,206,22,64,193,124,64,156,4,149,44,165,4,115,93,246,46,242,123,55,208,7,112,39,226,9,100,178,148,211,4,136,0,188,144,4,87,192,145,114,66,116,116,164,162,202,253,103,37,90,42,61,127,37,208,210,36,28,134,166,172,54,146,64,198,67,18,240,32,202,153,146,231,144,120,0,7,194,49,238,238,32,26,65,237,83,81,143,62,84,81,97,88,172,164,163,163,4,128,198,16,22,229,166,50,48,197,144,203,121,43,170,158,244,11,135,68,83,133,132,146,85,1,188,144,40,212,239,181,32,184,226,48,68,23,87,138,180,94,174,24,20,8,160,144,104,183,165,211,34,17,15,82,178,49,12,7,58,19,81,40,31,74,238,91,212,138,236,177,238,48,236,30,60,1,71,217,3,148,125,168,73,207,127,217,241,84,233,29,111,101,135,138,126,7,46,102,90,114,221,182,156,175,40,97,73,250,24,30,131,150,150,146,146,32,159,106,97,68,20,129,58,252,207,178,23,6,77,0,209,4,61,52,28,131,248,197,222,129,83,167,255,98,239,200,202,208,235,64,223,220,250,133,6,180,3,200,178,14,46,190,72,172,52,30,13,195,98,125,164,165,200,90,144,215,148,136,167,58,18,77,163,127,168,11,85,128,191,86,3,36,171,73,142,74,43,213,144,93,177,20,180,90,29,70,32,192,224,174,228,176,180,40,247,50,189,229,57,40,5,252,7,122,114,75,103,2,106,57,69,43,178,126,91,79,173,40,196,126,89,80,81,33,254,173,168,126,41,202,127,103,69,165,135,195,97,112,0,121,195,252,35,181,44,64,130,14,6,65,209,106,137,35,128,3,127,93,110,1,43,75,46,50,11,112,137,237,162,90,75,121,159,10,36,3,184,131,48,52,158,156,138,225,32,30,47,1,96,8,174,32,142,54,232,12,67,162,136,56,112,5,115,114,113,0,253,11,9,232,10,42,154,131,146,3,12,125,58,88,234,140,80,158,150,56,83,122,98,116,165,7,69,92,168,59,222,229,215,212,149,254,45,61,148,255,45,61,254,247,151,30,127,154,238,85,254,247,167,123,213,255,55,178,189,204,127,105,182,167,127,60,241,235,110,207,98,187,138,234,112,206,24,20,10,227,181,236,194,244,253,55,8,68,151,126,3,35,209,72,130,4,69,60,9,192,25,4,17,78,48,184,155,4,0,71,97,240,180,189,72,105,254,27,161,145,4,42,123,50,121,138,133,233,158,186,80,30,126,44,185,30,25,94,23,70,128,253,0,79,14,22,180,205,245,195,163,104,50,130,62,141,245,111,144,156,81,24,175,165,71,145,180,32,136,39,227,82,250,188,63,35,82,117,88,86,159,98,74,65,58,85,126,89,52,45,102,141,229,103,58,203,207,206,87,52,212,151,138,168,159,123,233,139,101,212,226,190,115,39,143,173,204,48,43,145,104,141,45,10,238,98,189,64,65,162,43,135,150,170,185,63,160,70,133,164,145,163,126,88,164,183,162,166,241,66,162,17,24,47,170,191,34,241,228,221,131,116,70,46,187,13,14,132,131,72,79,16,183,216,26,196,147,67,24,110,217,141,201,6,130,82,105,64,105,221,95,249,255,241,17,105,69,56,250,161,26,250,159,26,127,126,10,62,148,66,138,22,32,126,211,73,253,209,85,254,195,94,77,239,160,126,255,247,26,118,180,102,221,15,135,132,255,43,125,57,90,79,142,110,67,253,183,180,223,40,173,183,31,182,217,255,147,133,238,138,42,247,135,109,250,111,89,251,191,179,172,253,223,211,81,163,198,87,245,223,4,216,191,72,198,255,137,8,75,151,180,253,254,207,246,4,112,148,219,47,178,255,137,163,247,242,185,155,18,240,22,45,67,41,168,150,107,61,8,228,135,203,23,191,120,188,184,168,61,229,121,50,205,229,97,112,2,17,182,116,189,12,66,163,187,178,36,252,139,98,237,143,172,255,195,205,132,95,172,192,138,75,9,52,235,35,209,112,28,217,151,16,244,101,210,114,128,162,171,123,160,20,80,74,157,79,49,115,0,157,117,232,138,83,8,68,103,185,172,254,233,73,42,154,172,4,138,6,79,222,135,48,167,21,67,34,22,32,30,36,136,254,210,14,148,82,23,177,156,0,112,88,248,162,242,75,189,187,31,238,64,80,136,210,238,64,80,212,165,49,163,144,194,3,68,52,18,129,196,81,31,98,195,80,148,218,155,92,103,210,93,90,88,186,174,176,212,193,242,134,131,88,138,233,105,52,156,86,144,160,21,225,43,137,88,232,89,234,89,173,48,218,63,95,229,95,105,75,217,238,100,49,200,153,140,198,249,231,85,95,186,32,66,223,247,92,52,34,141,34,153,8,17,7,46,30,137,48,104,16,0,209,8,9,128,70,31,4,96,40,212,210,70,163,140,44,166,44,217,255,211,173,61,234,54,150,251,79,108,99,234,6,254,127,191,120,248,169,75,246,111,1,241,111,1,241,223,95,64,252,87,181,217,151,90,236,148,142,55,45,112,66,4,1,121,192,72,215,24,2,33,88,152,235,8,227,201,239,201,70,118,162,164,48,12,154,122,215,148,28,86,33,212,219,179,20,88,250,112,139,247,65,19,96,222,128,6,176,147,50,36,191,83,29,2,161,157,77,168,129,85,29,2,161,157,81,104,29,41,75,218,39,114,248,4,0,114,28,54,70,226,9,34,180,211,162,40,57,98,17,113,104,60,32,178,244,164,73,20,240,11,80,95,130,182,0,225,24,28,66,4,248,25,225,47,224,49,68,2,40,66,99,254,183,92,2,32,144,165,160,111,142,65,162,9,20,57,169,107,70,221,49,148,32,189,104,85,170,47,81,235,27,200,143,119,142,40,168,84,34,216,165,44,255,211,115,180,95,66,81,87,135,214,194,163,24,157,246,13,0,53,8,68,18,176,164,156,63,37,241,72,4,72,215,22,179,48,215,161,52,182,144,228,16,108,249,195,240,190,95,228,213,197,217,255,154,5,253,43,131,211,114,228,226,244,111,150,248,7,200,31,9,253,150,2,101,209,255,134,192,111,36,161,119,3,234,252,127,216,25,86,112,167,16,160,39,248,11,199,88,41,207,111,48,200,78,242,127,251,75,83,255,15,189,254,242,251,127,88,39,105,23,12,245,46,62,12,139,148,134,161,209,24,234,119,32,240,82,88,39,41,23,204,63,224,241,251,239,255,201,202,200,41,40,253,240,253,63,5,25,37,133,127,191,255,247,223,241,34,23,102,228,100,235,2,162,65,28,140,86,180,80,157,64,210,5,68,75,186,96,164,0,93,51,192,212,204,10,208,211,53,178,146,34,31,53,104,215,18,240,148,171,243,172,43,128,1,79,89,41,57,21,41,89,186,153,197,103,53,158,242,82,178,170,212,25,60,134,136,131,131,212,70,227,207,222,69,105,98,47,133,95,24,22,9,129,32,221,41,223,229,18,129,80,105,226,64,103,20,8,39,0,59,93,48,24,23,20,40,229,130,65,193,208,46,82,24,156,139,244,98,72,151,166,193,72,211,35,236,164,225,35,221,177,168,223,35,19,209,4,164,59,40,189,4,189,19,194,138,0,241,112,28,18,75,192,224,176,78,191,69,166,124,221,64,154,30,124,39,132,117,73,228,37,81,68,33,16,56,6,141,167,104,37,45,13,216,128,56,164,51,185,94,132,17,0,130,43,18,79,183,34,148,106,8,73,46,121,156,157,145,112,36,181,66,35,98,37,9,24,73,4,140,0,74,65,88,161,128,6,176,36,171,148,30,185,68,133,131,180,43,37,34,114,50,128,36,221,172,9,18,77,155,17,253,137,241,79,122,255,39,216,210,113,132,121,211,6,1,73,64,78,70,148,172,186,39,12,7,56,35,81,32,148,236,3,80,24,22,9,165,243,1,40,181,191,12,122,19,172,40,95,221,208,0,236,29,232,248,120,19,64,52,153,154,17,218,25,227,7,97,245,131,176,178,82,198,16,32,130,12,175,6,0,34,98,244,230,151,50,161,124,217,207,140,114,230,198,139,138,160,145,40,81,137,69,36,50,33,42,150,136,152,33,129,128,181,32,162,192,101,16,125,36,136,66,168,45,61,111,84,148,145,147,145,37,143,155,82,190,77,177,244,218,73,107,153,35,165,92,9,4,236,78,50,132,21,204,133,14,0,216,73,125,4,73,37,128,193,18,36,200,153,84,99,9,90,31,137,2,209,203,52,119,254,245,206,32,131,7,72,144,83,39,165,147,64,211,128,122,241,157,114,218,251,107,205,165,40,86,167,186,27,6,75,171,138,150,36,95,84,30,32,11,69,46,203,201,162,170,67,88,245,160,134,212,129,221,127,186,94,246,50,14,139,75,172,255,123,20,128,126,119,74,145,129,117,151,164,255,51,31,193,193,188,200,40,20,23,33,155,216,15,194,42,227,45,3,147,0,100,188,101,41,127,149,21,40,127,229,40,127,101,200,127,149,228,201,127,229,156,41,239,101,233,198,85,127,28,87,2,233,254,58,211,168,145,25,208,208,20,150,209,168,211,84,80,101,42,3,112,153,52,149,253,18,137,165,247,178,148,113,25,149,21,130,146,25,172,144,20,252,181,164,84,253,100,229,255,177,150,100,6,180,9,122,206,10,203,64,127,36,59,133,189,28,149,168,50,157,13,156,169,38,162,14,193,41,127,21,151,101,249,61,81,37,170,6,20,120,37,37,58,13,20,150,233,40,203,83,25,200,211,17,82,165,35,77,71,142,58,251,39,218,200,83,180,81,160,216,67,6,70,97,32,163,240,59,19,81,151,78,22,164,91,161,149,70,0,126,105,131,69,81,40,139,252,231,70,160,160,41,32,232,140,64,39,156,18,157,137,20,156,233,25,252,214,65,101,41,200,170,148,89,21,170,226,242,203,75,42,67,241,25,57,234,184,19,197,68,114,203,122,203,129,116,12,126,225,118,127,225,178,52,61,254,194,164,138,244,122,195,169,139,172,184,60,241,251,245,80,144,91,54,17,109,255,35,150,5,162,105,143,160,91,3,5,58,6,180,45,46,191,108,95,37,112,153,129,28,221,251,191,210,245,151,222,69,97,240,219,37,165,45,38,157,78,138,212,109,5,255,123,150,74,202,63,123,145,226,50,168,156,243,111,73,252,126,22,241,39,110,74,111,89,184,196,15,59,156,170,177,156,243,143,59,227,7,198,63,5,187,191,8,203,84,114,50,74,127,105,235,229,157,44,79,201,142,127,146,60,92,48,203,245,197,82,155,201,47,192,15,194,250,7,5,4,165,25,165,6,208,10,193,197,234,111,37,40,153,208,15,69,197,47,174,99,74,75,3,178,106,63,39,98,72,192,31,41,129,0,177,70,8,239,37,37,228,229,200,41,112,81,186,21,117,137,26,72,173,146,64,64,82,243,239,228,150,149,248,81,44,10,5,114,109,75,121,206,78,38,241,179,196,172,114,20,52,123,57,53,57,135,197,134,41,158,232,36,137,66,226,9,148,190,32,245,103,23,0,12,145,128,37,82,111,150,252,49,14,18,189,140,66,149,206,94,246,175,80,192,165,186,104,73,224,69,163,216,203,168,201,254,29,210,162,157,232,112,100,126,141,67,41,187,232,152,4,64,32,148,139,7,72,52,146,32,34,10,248,253,237,234,209,0,3,168,104,127,8,237,7,97,69,58,255,109,109,181,67,3,64,35,81,100,96,86,106,247,7,194,26,0,97,93,201,130,188,168,43,104,67,88,41,207,1,188,1,60,1,71,132,19,252,2,32,172,24,34,1,80,163,47,244,201,155,102,31,17,137,66,128,56,63,90,237,170,70,55,77,174,199,232,166,89,13,48,230,212,179,156,57,140,224,170,6,44,86,123,100,42,102,206,34,222,126,1,162,82,230,110,46,228,73,17,74,205,205,106,65,173,233,168,187,79,237,79,75,64,10,170,41,209,93,15,77,116,199,211,234,104,153,197,65,218,211,15,202,248,210,224,82,245,140,87,3,100,23,7,105,141,189,101,200,0,242,31,3,106,164,160,175,232,255,48,184,144,177,117,65,44,217,159,208,112,31,35,52,2,244,38,211,249,195,93,189,226,152,66,62,239,80,69,248,211,74,156,124,86,144,162,172,5,121,101,255,206,97,52,200,251,146,82,133,255,232,38,191,171,187,209,72,212,223,131,47,71,218,63,2,95,142,105,100,240,128,127,27,126,255,101,175,63,237,255,145,3,197,63,110,252,209,94,127,247,251,95,242,50,242,63,253,254,151,204,191,253,191,255,150,215,255,140,254,31,213,187,254,135,54,254,126,110,221,177,226,125,208,112,96,39,249,239,255,223,251,120,148,106,97,169,117,68,45,26,200,37,7,158,0,35,44,223,213,167,163,65,77,196,150,228,105,8,43,30,233,11,234,192,224,174,224,15,80,150,139,227,16,86,34,218,13,141,241,66,235,83,251,91,203,32,214,244,227,16,138,5,44,65,242,242,224,1,216,98,201,72,192,208,126,140,129,178,16,56,178,132,148,107,173,32,94,138,140,64,65,178,0,157,169,247,182,237,241,20,116,12,206,193,158,230,32,228,210,86,23,3,39,46,253,252,19,89,71,169,37,48,234,197,126,234,147,67,4,245,87,137,164,32,172,150,180,233,197,39,102,75,15,25,213,104,45,64,186,246,223,34,41,9,218,83,71,224,24,30,131,86,219,185,52,140,113,71,18,64,119,44,193,103,167,35,69,86,93,144,0,226,220,145,104,144,90,137,90,91,24,3,88,24,129,0,226,208,228,245,117,135,17,224,174,139,183,14,104,250,226,165,0,43,242,251,69,48,56,12,13,56,129,20,98,68,252,226,117,7,24,122,233,130,153,159,11,72,240,199,18,9,254,88,12,158,224,143,0,81,32,1,244,199,146,9,7,44,255,100,154,246,226,47,104,81,71,40,212,168,132,169,23,142,64,4,64,196,47,254,114,146,48,21,86,152,90,42,47,219,157,90,15,80,188,21,134,3,1,24,30,143,252,255,216,123,243,230,56,142,35,81,124,255,197,124,138,126,252,67,15,144,135,131,233,185,112,56,248,139,128,72,16,130,5,2,52,14,201,182,158,2,106,204,244,0,99,206,165,57,64,192,10,69,144,214,97,201,75,138,242,90,235,131,214,250,148,44,61,251,73,148,119,189,50,45,209,171,15,99,14,0,254,165,175,240,139,58,186,59,235,236,234,70,207,16,34,200,8,65,64,119,85,94,149,149,149,153,149,85,189,221,244,238,243,187,76,200,157,245,90,143,249,81,212,230,130,219,227,158,92,238,11,79,90,93,254,209,5,204,10,223,14,49,198,61,35,151,141,165,198,46,251,130,133,205,241,35,127,72,55,91,77,183,85,157,61,67,165,75,71,105,157,43,51,241,106,204,73,172,112,117,167,213,117,233,174,41,30,180,118,155,30,223,216,113,173,167,215,215,47,251,213,125,8,214,86,171,178,143,75,168,94,124,242,69,18,12,57,237,54,18,173,83,175,179,128,241,161,4,171,236,180,123,253,78,80,122,210,118,122,152,65,95,1,32,34,31,120,139,86,122,32,4,8,202,142,179,139,113,52,247,25,138,112,135,96,4,151,87,214,231,103,41,135,85,183,211,241,174,95,241,107,106,218,29,183,235,54,123,150,211,163,151,241,180,207,146,43,138,88,193,96,96,176,186,42,147,26,123,10,95,162,163,152,65,83,193,12,194,44,176,179,7,63,226,103,206,10,77,119,103,36,163,67,183,156,13,135,7,131,243,59,97,137,88,207,237,184,77,79,136,204,173,106,160,250,149,176,231,85,219,160,201,135,33,57,93,56,240,16,42,39,231,245,227,200,153,192,149,9,218,219,113,215,10,220,206,5,18,247,143,201,96,57,35,145,251,143,158,18,7,131,109,205,143,202,92,165,82,163,219,16,68,33,107,205,74,173,185,221,197,138,72,206,209,16,75,152,177,150,201,169,18,191,5,226,29,195,192,90,223,106,246,156,90,211,114,154,214,139,142,15,115,211,107,252,162,23,166,239,184,141,174,91,223,117,187,214,56,54,60,53,20,32,77,78,146,194,48,183,139,111,123,107,56,251,228,2,178,45,82,195,72,36,89,113,221,246,68,38,53,22,80,252,148,71,201,243,47,248,198,67,34,57,59,221,113,219,68,114,18,202,136,252,28,1,40,39,69,89,79,40,75,47,235,48,190,103,5,233,38,11,151,193,146,108,193,147,123,214,57,127,149,70,49,125,173,202,44,165,93,167,234,206,99,235,91,193,249,130,70,13,69,252,79,40,115,5,141,238,182,191,211,51,54,214,232,178,249,129,239,48,171,252,74,21,184,16,184,154,195,237,140,239,77,76,224,142,153,53,228,163,209,230,40,190,29,111,212,38,82,99,175,40,88,90,195,10,58,62,225,105,234,203,41,154,218,144,99,71,109,86,170,227,123,19,1,56,0,12,151,121,209,182,72,76,114,148,184,213,42,241,252,198,39,216,13,43,218,25,145,17,73,98,26,233,63,241,132,181,7,51,55,177,101,91,171,90,141,110,102,169,229,84,160,116,39,172,115,1,108,181,252,199,94,241,147,70,86,163,139,243,70,222,95,53,143,0,95,176,216,49,105,119,220,50,114,114,103,173,141,110,224,16,102,160,244,50,65,82,199,170,53,187,61,215,169,100,196,81,9,26,141,79,88,227,100,83,47,77,82,155,19,96,188,149,130,166,137,137,133,239,45,94,30,159,160,29,95,206,170,20,106,193,237,121,14,27,163,85,181,42,59,12,20,235,94,198,107,13,101,114,230,76,0,189,193,65,167,62,195,248,132,204,145,32,136,26,18,68,141,12,109,3,241,144,92,136,130,141,5,60,215,89,14,210,86,235,10,82,159,189,12,164,36,51,206,120,83,19,223,68,173,24,38,177,143,37,231,143,71,123,185,31,7,237,229,190,12,45,118,228,12,209,182,186,177,240,182,186,82,196,216,95,52,195,76,28,201,24,184,73,71,9,118,207,53,53,228,28,249,172,113,88,71,253,100,188,19,31,216,12,57,113,142,199,39,172,39,201,111,232,37,171,204,6,148,144,174,18,82,60,215,219,80,227,145,187,97,54,105,81,75,83,22,161,67,100,6,29,246,48,197,34,250,17,227,19,140,39,161,67,40,118,150,200,140,222,146,42,216,156,224,154,117,132,66,120,63,62,225,119,134,70,2,68,246,147,147,214,37,167,141,75,77,176,211,182,48,191,158,65,70,159,132,15,245,26,113,163,156,102,197,218,118,201,221,235,176,100,222,217,106,145,112,13,121,165,56,13,132,130,102,138,65,234,124,2,223,115,219,237,81,207,40,141,35,47,226,250,176,196,94,238,235,136,189,188,1,137,237,184,237,58,185,67,219,241,201,201,164,198,40,8,41,53,249,128,154,118,223,128,154,86,87,75,206,202,26,164,167,220,113,201,149,195,1,57,40,60,163,23,196,19,177,90,14,174,103,70,100,82,216,82,58,11,128,206,86,55,156,80,98,132,52,164,94,152,95,154,95,159,7,196,226,228,128,32,187,0,142,148,172,98,64,22,73,46,132,75,16,217,39,157,8,231,214,207,63,13,200,234,183,43,188,12,51,56,154,39,80,164,84,149,128,176,80,195,80,162,232,141,228,12,85,248,120,25,121,14,146,50,193,13,16,248,136,206,62,29,68,76,186,151,165,34,161,8,138,100,48,160,90,179,92,239,147,243,49,56,50,121,145,130,163,97,76,112,115,254,211,243,115,23,112,252,126,230,201,51,72,30,117,215,33,95,65,192,96,32,138,126,147,158,16,162,196,248,249,161,12,189,221,160,94,57,91,118,58,21,146,35,35,100,87,251,117,12,7,19,79,55,197,8,173,222,221,234,244,176,61,66,253,156,187,101,141,63,189,126,105,105,194,42,227,90,124,52,171,169,148,36,107,133,48,2,211,193,8,16,25,74,134,128,115,21,177,239,34,177,112,140,43,207,186,28,17,90,35,71,193,188,57,93,219,35,192,199,171,177,121,123,186,102,170,59,160,104,90,167,126,228,36,96,115,219,107,131,181,99,215,237,108,101,136,106,139,99,244,112,115,185,108,154,166,214,149,208,61,246,76,173,89,49,73,179,94,169,53,43,92,68,141,31,241,233,136,117,154,48,19,50,169,20,55,69,123,25,53,49,88,173,16,40,14,45,126,164,138,220,133,33,16,67,120,161,73,146,177,188,61,138,88,94,194,100,2,65,189,4,170,46,186,87,53,79,48,204,183,79,67,152,47,200,209,56,222,151,140,192,80,2,127,59,84,251,22,220,30,178,35,102,174,62,106,169,113,241,229,224,73,101,139,9,248,203,56,91,207,131,23,235,168,3,174,163,22,80,139,242,146,86,78,71,175,41,182,12,74,138,131,90,191,72,245,208,166,181,165,164,152,176,130,75,4,179,185,160,14,148,128,51,44,58,245,107,50,105,125,175,195,192,193,28,192,42,81,208,161,148,231,185,33,180,147,50,91,90,78,43,150,214,206,4,68,196,69,0,126,82,74,243,160,234,18,148,11,219,4,1,17,142,138,22,90,3,13,132,163,4,39,67,12,6,153,197,172,171,47,214,34,230,160,33,4,20,115,1,96,6,67,74,133,147,23,208,23,140,208,35,4,176,226,88,9,20,14,47,33,2,235,30,172,85,135,227,55,229,61,199,28,144,110,197,136,2,137,128,128,80,87,2,212,129,226,96,230,0,3,25,222,105,192,77,41,132,44,172,69,144,46,19,208,184,101,190,40,136,43,15,134,55,159,22,42,167,43,128,174,105,5,93,176,62,29,255,30,90,178,13,78,113,136,245,233,50,138,184,34,114,165,57,241,100,0,202,227,225,217,5,98,248,92,237,240,26,160,183,115,96,144,225,12,40,1,203,74,244,100,106,6,8,112,74,55,176,76,153,125,14,142,1,4,68,140,71,30,32,174,0,206,32,213,96,222,192,115,7,180,166,159,30,19,209,211,91,54,160,183,172,68,15,56,16,240,23,84,136,115,129,10,192,213,144,158,8,42,128,159,51,218,67,22,180,67,153,50,27,140,205,12,104,83,16,158,76,165,225,1,13,60,209,182,128,16,242,10,173,207,25,105,189,184,112,226,179,64,81,78,101,88,236,161,12,130,88,42,28,48,147,181,194,41,68,20,11,105,79,84,192,59,170,51,149,150,218,31,213,212,203,17,91,180,5,6,217,78,171,102,62,111,139,66,167,126,40,122,110,225,4,135,141,182,228,162,136,224,67,200,224,96,14,84,75,118,65,46,58,102,61,208,58,12,197,28,224,64,5,40,198,241,28,11,156,197,9,14,124,37,120,60,199,2,167,115,240,76,78,250,120,14,68,25,32,72,240,120,142,128,32,233,227,57,16,49,56,54,152,204,241,156,113,205,105,4,26,157,172,52,203,174,213,221,111,150,51,232,183,240,246,248,138,181,115,161,65,79,106,34,37,59,112,161,138,38,105,132,132,130,53,19,130,51,23,90,227,8,58,73,220,152,210,12,131,127,239,118,83,140,222,164,255,68,106,236,149,9,227,24,25,245,144,159,145,146,164,50,172,115,86,195,185,226,142,195,35,216,32,147,144,182,114,19,122,64,186,83,86,202,195,81,220,241,165,224,132,145,44,119,16,28,200,130,7,150,132,118,210,3,85,128,80,217,73,42,91,56,73,229,215,54,144,172,160,226,72,148,136,156,158,37,146,157,244,202,72,10,124,78,202,81,171,176,46,210,163,86,230,157,36,71,173,20,125,34,30,181,18,78,54,201,207,88,137,205,100,135,171,64,194,69,126,170,170,86,181,254,151,46,9,107,82,23,148,153,223,195,159,164,236,32,3,134,204,199,174,5,166,75,218,170,89,56,21,6,158,145,244,94,247,106,173,87,222,177,118,173,217,115,214,46,216,104,159,248,166,85,35,45,202,78,215,181,178,179,232,87,207,68,60,177,155,233,146,188,61,125,109,11,175,131,188,61,109,146,227,155,48,249,124,244,142,222,228,204,180,195,7,126,72,170,241,21,35,73,216,137,73,66,180,20,39,81,36,186,67,121,80,61,86,154,110,171,250,92,199,105,183,221,142,204,154,142,113,123,99,254,37,22,220,46,152,244,121,171,43,127,65,119,182,164,125,240,30,150,236,13,221,173,242,94,189,114,226,15,21,138,75,164,241,105,194,156,236,52,97,246,152,167,9,197,213,211,232,24,161,184,150,161,110,96,177,246,80,134,234,155,238,224,32,48,134,234,19,131,210,68,179,228,236,159,212,79,208,183,123,124,56,48,193,127,38,231,255,182,91,153,70,171,18,31,135,254,252,95,54,107,23,138,220,249,63,219,206,231,30,159,255,27,197,63,50,248,196,191,220,238,180,250,237,224,243,235,50,93,72,165,182,91,150,157,177,75,169,84,199,125,169,95,235,184,150,250,52,157,181,107,103,242,217,76,246,241,12,61,185,255,12,231,127,183,223,136,143,35,100,254,219,249,2,127,254,215,182,75,217,199,243,127,20,255,182,107,189,157,254,86,166,220,106,76,146,25,204,204,222,98,38,75,173,191,181,99,207,94,236,174,44,63,187,58,183,54,179,62,213,93,252,198,210,226,70,227,185,245,106,249,187,87,158,94,41,56,139,207,93,253,193,78,217,89,155,107,125,107,165,186,120,229,92,138,1,140,44,196,228,118,235,108,185,209,182,118,179,153,98,166,136,224,61,179,179,55,213,221,237,156,111,55,246,246,122,79,63,245,82,241,251,185,70,123,114,239,217,239,119,107,211,59,223,190,84,93,94,218,253,214,197,185,122,103,97,123,35,20,30,32,115,119,186,178,94,89,218,186,180,144,187,178,88,158,220,253,214,110,253,27,213,82,241,217,92,174,178,117,229,59,91,173,171,243,165,239,111,175,79,110,47,63,181,55,127,46,5,204,214,222,228,30,190,125,184,139,64,102,51,217,179,185,172,61,99,231,178,5,123,38,91,204,151,206,206,108,85,170,206,150,91,154,46,22,242,8,207,252,212,246,55,102,22,22,215,95,202,78,237,180,171,157,213,126,169,180,248,236,5,119,239,146,115,165,186,91,204,185,75,223,203,157,255,206,83,207,213,158,233,20,98,227,1,108,45,78,22,127,80,154,153,238,54,103,158,113,166,215,221,111,149,103,46,61,211,105,109,108,84,95,122,234,41,167,255,220,247,191,253,210,210,183,114,43,151,171,141,239,102,17,58,157,81,206,149,50,217,179,157,114,198,6,224,191,95,223,217,89,89,219,93,175,60,51,191,179,181,177,180,254,253,221,74,97,110,245,153,153,237,206,197,167,218,217,153,253,231,190,241,220,214,119,39,215,247,191,189,117,53,12,60,178,249,8,228,149,203,151,91,139,219,213,252,122,119,126,183,211,200,94,190,232,218,197,111,125,251,27,197,169,236,183,159,221,251,238,15,230,119,119,159,126,233,252,206,51,223,40,55,183,77,64,2,98,159,126,118,250,219,43,149,201,165,226,244,247,190,209,172,79,119,10,121,119,231,217,229,239,45,110,76,62,61,191,88,90,41,95,124,233,234,165,133,153,246,183,158,45,44,158,123,188,250,232,254,153,216,127,252,12,255,186,217,106,199,184,2,54,228,254,87,59,159,205,242,247,191,150,242,143,239,127,24,201,191,135,127,255,131,76,187,216,155,32,232,159,39,225,46,136,199,151,192,14,239,18,88,18,221,67,69,120,88,247,192,146,82,61,205,45,176,89,221,45,176,245,154,211,213,94,1,155,133,87,192,6,205,165,119,192,170,102,7,189,6,214,128,105,76,124,18,60,23,179,74,158,183,91,155,61,103,91,207,116,49,11,14,242,4,237,227,112,157,216,229,183,180,38,19,143,1,190,242,54,75,175,188,157,163,79,158,136,160,158,244,218,91,19,202,224,152,232,8,35,114,34,148,21,179,152,178,133,214,58,126,18,137,50,91,114,33,175,170,87,148,146,82,37,102,93,113,105,197,96,227,91,187,133,44,221,163,14,42,4,138,224,6,86,230,74,216,227,93,212,11,106,28,20,180,107,110,196,181,12,46,196,13,234,76,98,220,136,107,25,92,136,27,92,230,105,126,35,110,94,40,32,132,165,59,84,164,54,37,2,212,29,198,189,23,55,78,149,70,164,123,113,245,234,16,148,102,86,48,83,211,132,125,109,221,42,44,129,212,8,135,136,20,33,96,100,90,226,69,84,132,140,219,193,91,42,216,74,136,96,177,22,69,151,44,175,99,68,176,37,192,7,115,45,111,20,153,250,101,68,211,24,205,244,84,136,72,65,253,109,81,16,142,32,22,90,88,84,77,63,26,247,254,154,84,240,61,186,247,254,154,168,105,236,59,128,149,139,213,72,174,1,14,243,201,188,107,128,121,64,176,169,80,192,162,100,201,224,82,96,228,225,196,191,17,152,120,38,218,254,12,229,39,186,92,37,172,244,100,200,55,3,43,71,81,85,184,18,214,129,47,97,81,186,122,242,98,150,19,188,89,31,230,112,30,239,18,224,220,49,182,237,195,172,75,232,6,126,216,92,14,189,10,56,52,12,80,109,234,43,213,67,190,189,111,224,244,115,27,248,6,150,215,180,199,227,205,255,100,255,153,228,127,187,87,157,237,109,183,227,253,63,225,239,127,229,10,89,155,223,255,43,100,139,246,227,252,239,40,254,61,252,252,175,160,93,108,242,151,62,126,52,211,191,143,47,18,246,115,193,147,147,86,175,133,120,244,70,28,95,153,64,46,167,88,35,79,30,246,21,195,235,181,94,221,67,72,19,116,254,63,241,166,155,172,157,5,151,5,245,80,95,238,54,8,242,140,185,133,130,248,220,17,80,128,123,126,136,55,204,225,160,15,25,36,158,107,133,228,111,132,132,185,181,199,239,203,97,130,111,24,116,151,157,142,211,232,18,240,207,191,240,36,29,76,252,84,142,174,20,220,153,217,198,125,133,91,52,240,67,213,61,26,64,91,196,27,52,192,203,56,119,103,80,221,244,255,47,84,233,142,224,10,13,134,191,4,46,207,96,224,233,174,205,16,27,198,184,48,195,64,130,143,252,189,25,64,144,198,55,102,48,194,143,124,87,134,92,234,38,119,101,50,120,23,220,30,54,130,102,215,89,224,166,154,235,50,120,208,196,248,153,193,190,68,175,30,55,6,14,140,158,25,6,208,33,2,26,98,236,200,101,126,140,165,211,223,251,129,58,169,46,241,99,192,60,196,229,111,217,105,184,112,97,210,93,185,132,126,112,86,27,63,98,22,134,85,82,65,90,177,182,90,173,58,187,246,236,58,157,90,179,151,102,238,157,38,141,133,11,166,233,99,110,133,195,135,46,212,164,230,225,138,134,219,10,171,25,121,26,178,200,224,65,81,174,50,248,237,16,150,153,145,220,212,196,114,152,220,58,67,1,26,44,52,176,101,242,43,205,169,184,161,9,74,50,234,82,67,197,63,204,181,198,214,169,220,130,219,67,38,199,204,90,47,227,68,110,152,153,14,32,123,182,103,124,130,88,31,253,5,175,164,45,132,95,117,234,93,87,143,130,26,33,211,213,6,55,150,223,254,20,38,219,145,23,200,192,85,79,93,49,98,107,170,100,40,3,218,146,17,27,214,201,192,14,210,154,17,105,30,97,40,95,75,102,194,81,26,172,158,35,252,226,18,141,53,255,89,168,53,210,126,50,89,218,37,74,121,134,118,38,198,253,100,50,189,23,99,138,223,136,101,238,135,202,49,237,241,102,159,73,7,243,79,38,23,180,187,137,199,172,196,16,17,7,87,213,36,82,137,33,114,172,219,112,37,183,149,204,96,209,145,189,114,90,59,128,111,249,40,154,141,71,176,171,174,188,235,76,188,43,138,189,202,133,239,133,119,175,183,48,154,105,178,39,109,94,40,17,2,90,118,181,22,30,3,131,82,15,74,215,116,218,164,216,0,222,189,100,140,32,23,140,10,28,137,80,69,0,119,163,41,202,37,40,237,51,17,105,247,208,7,149,13,70,138,40,162,39,156,149,211,92,125,202,20,115,171,21,188,242,167,146,230,138,60,182,28,5,237,102,55,23,5,8,196,194,7,67,77,231,175,226,97,201,5,213,37,44,107,98,211,160,66,140,0,133,234,88,86,18,4,62,126,110,70,145,230,90,30,230,178,36,79,51,193,245,113,230,23,2,201,0,105,111,57,132,247,105,17,170,139,64,139,192,91,230,134,34,213,69,65,211,105,225,150,195,168,8,68,147,48,149,230,38,29,177,202,158,154,2,51,103,126,9,33,165,81,13,154,16,26,84,89,17,208,244,243,241,21,158,58,243,197,146,171,155,3,90,148,68,225,156,88,132,132,16,36,88,56,23,204,127,12,45,108,61,128,6,192,78,27,22,62,113,211,13,136,72,156,110,218,75,203,12,199,38,80,83,82,100,86,4,107,111,164,219,171,44,69,141,89,112,249,218,49,111,175,82,213,152,97,14,132,34,179,124,54,28,37,119,123,149,170,198,76,97,174,163,223,94,165,170,49,11,38,218,49,111,175,82,249,175,58,45,58,254,173,86,90,15,92,125,185,149,182,155,112,199,149,182,181,228,170,43,131,0,93,122,227,85,40,51,202,139,175,76,248,129,169,21,197,253,87,161,96,84,215,96,133,118,52,141,180,227,95,138,37,135,167,43,61,20,131,108,139,251,7,202,249,64,99,208,151,36,35,164,157,65,45,31,108,108,92,243,152,11,171,121,228,107,21,229,2,8,191,115,11,110,150,144,157,63,201,213,88,44,11,57,166,84,145,34,140,82,235,152,245,88,100,0,40,209,18,169,231,73,69,96,126,54,111,94,225,104,216,71,90,225,168,232,34,173,112,36,34,125,222,142,85,225,104,31,187,194,81,62,246,170,242,70,109,107,190,182,81,158,36,57,238,45,93,161,187,148,73,93,81,5,39,249,73,188,156,202,92,38,201,93,219,197,24,175,147,40,148,147,93,35,171,93,236,142,119,175,149,125,140,2,89,237,2,24,90,29,171,93,61,66,111,185,210,171,110,104,101,173,62,119,171,42,171,149,91,38,121,77,109,88,166,150,43,143,13,115,38,140,154,63,46,165,125,252,207,168,254,23,187,58,81,139,126,193,63,109,253,111,174,128,94,242,247,255,76,229,31,215,255,142,228,223,195,175,255,37,218,197,22,253,146,171,198,78,66,197,239,227,154,93,125,205,238,193,239,222,56,248,245,103,131,155,183,142,62,249,100,240,254,95,31,252,232,198,225,237,215,30,124,252,238,193,191,127,74,170,151,214,59,237,242,37,103,187,134,226,130,94,62,199,202,11,141,243,253,187,55,15,223,253,232,232,203,95,222,191,251,167,193,181,123,95,221,187,113,255,238,231,247,63,127,227,224,214,59,247,255,231,87,135,95,252,178,189,53,248,219,7,131,215,255,118,248,238,111,14,222,124,231,254,23,127,56,252,237,245,212,152,15,119,115,125,245,242,249,205,11,243,23,231,54,150,214,55,151,87,150,231,1,206,115,86,214,71,68,136,124,240,197,47,142,62,121,255,254,63,190,244,145,82,106,121,136,151,230,22,22,207,111,62,59,183,180,193,2,204,229,139,57,239,156,127,179,223,176,118,157,122,223,181,26,78,155,124,182,222,111,234,239,31,7,112,113,236,120,14,181,125,30,11,227,5,82,24,128,252,191,44,118,57,206,8,188,224,253,110,132,114,150,190,4,100,157,33,119,171,6,240,9,41,4,1,1,237,199,212,99,18,208,244,158,82,17,238,172,133,185,196,224,39,130,18,7,31,209,4,230,124,124,194,122,50,16,204,203,169,177,54,114,128,155,238,213,241,160,97,106,236,201,182,117,206,218,11,170,133,96,205,4,0,104,86,95,132,208,6,197,69,25,88,154,146,102,55,198,81,203,229,126,99,139,150,225,248,72,1,74,166,176,69,232,12,234,99,100,69,46,224,148,146,219,236,55,252,176,16,2,149,98,69,45,101,248,208,115,128,233,137,80,84,10,65,82,166,37,24,200,27,94,178,82,129,41,170,137,2,221,86,87,15,113,74,18,185,122,8,112,171,41,79,101,166,244,225,237,215,238,127,126,227,232,203,95,13,222,252,236,224,223,63,61,184,249,201,224,238,135,135,127,249,98,240,235,127,69,13,15,127,245,201,224,173,155,7,239,222,57,184,113,253,254,221,247,15,63,188,73,222,73,187,125,117,239,54,234,99,103,172,251,119,175,13,62,127,247,254,221,107,135,31,191,123,240,209,239,6,247,110,133,224,201,101,172,131,255,190,62,184,119,43,188,181,111,25,47,56,61,231,98,199,105,184,120,248,149,22,50,10,37,99,2,92,98,207,54,150,231,86,191,187,121,113,117,238,210,188,4,53,52,148,166,92,168,48,173,173,175,206,207,93,210,160,178,67,236,39,211,158,177,163,44,54,189,61,61,195,179,141,109,169,237,189,128,84,2,75,202,98,8,183,168,16,254,172,5,45,42,131,128,196,206,130,57,101,176,177,102,149,21,26,111,94,217,142,225,102,150,67,52,74,115,203,161,78,222,236,218,58,179,203,97,79,200,252,218,130,249,229,240,12,219,12,179,83,68,111,142,37,74,150,184,89,182,69,179,76,204,136,153,113,198,77,253,23,131,55,223,40,28,126,120,243,171,123,183,23,151,23,215,39,47,204,173,207,77,94,156,159,191,240,212,220,249,103,38,207,47,173,172,205,127,117,239,198,224,245,207,238,223,253,24,255,53,184,251,225,253,187,55,7,119,255,120,255,238,237,193,143,127,71,208,32,232,168,59,49,234,23,23,191,243,244,252,220,133,249,85,235,27,88,126,107,189,142,235,52,22,155,181,222,37,183,231,96,41,207,173,207,137,109,183,90,149,253,113,2,118,240,249,173,193,155,63,31,220,248,217,225,237,215,8,138,9,212,207,35,76,135,231,162,235,86,158,114,202,87,16,174,175,238,189,121,244,225,31,7,183,126,114,248,241,207,14,255,253,131,175,238,221,120,240,231,95,220,255,199,219,7,159,254,245,254,63,110,126,99,240,201,237,131,159,127,246,213,189,183,16,108,143,59,37,224,243,245,86,215,245,56,56,250,242,215,7,111,127,48,248,183,27,7,255,125,253,240,255,126,254,224,231,255,121,244,217,235,7,63,255,236,240,246,107,131,95,253,250,224,221,207,14,222,251,124,240,230,103,247,239,222,60,186,246,234,209,47,127,18,44,67,148,74,221,66,4,23,33,228,226,99,55,122,112,235,103,131,107,247,136,225,228,96,128,69,71,138,194,91,112,200,208,211,129,130,11,139,20,30,180,169,155,168,147,2,182,13,96,211,129,141,6,27,117,82,192,206,1,216,96,240,163,193,247,58,42,112,228,1,14,79,9,162,33,192,189,20,208,11,33,235,47,215,131,89,129,121,204,198,107,176,122,245,197,3,73,2,29,233,107,52,22,248,117,94,250,218,19,37,110,82,144,54,193,194,0,139,60,207,132,225,50,127,102,150,223,129,85,173,247,132,37,210,220,86,52,193,108,145,38,57,69,19,159,181,89,43,175,104,66,88,195,96,10,50,15,131,99,149,245,49,120,213,224,189,12,190,115,184,159,33,160,27,165,167,33,32,79,222,215,200,233,124,13,1,127,66,222,70,78,240,54,4,76,195,246,55,120,147,160,247,56,164,74,151,184,207,145,131,62,7,117,33,94,255,175,7,63,255,152,143,178,192,90,169,90,222,14,62,254,195,224,238,221,193,205,127,31,188,243,19,4,10,195,129,198,194,239,205,216,90,222,202,6,56,188,245,109,112,239,135,8,48,134,55,184,117,131,128,15,7,188,58,191,54,191,174,0,28,22,62,113,61,36,230,59,192,105,98,190,33,175,82,43,142,137,21,204,107,128,36,220,188,50,40,102,37,86,149,160,80,68,81,28,62,153,141,11,228,39,183,113,65,103,83,27,7,208,141,222,198,1,228,201,219,184,124,184,141,3,248,19,178,113,121,133,141,3,152,70,99,227,130,121,99,98,227,56,165,75,220,198,229,37,233,174,183,222,60,120,239,255,5,214,13,31,235,243,114,243,18,211,70,92,117,218,107,140,239,65,172,206,229,213,149,245,149,205,103,109,17,32,178,99,122,115,3,155,51,182,134,65,99,98,104,60,42,128,41,97,96,132,219,17,31,2,177,33,130,165,128,224,88,51,193,48,205,219,8,166,91,184,129,96,177,140,210,58,176,152,147,55,13,5,157,105,96,145,39,100,23,10,130,93,96,209,12,219,40,48,218,173,183,8,162,114,37,110,14,10,162,57,184,127,247,227,195,219,175,29,125,250,234,225,187,31,241,142,207,121,167,94,55,9,232,73,239,175,238,221,24,220,120,253,224,95,255,223,224,157,27,7,31,127,240,207,107,215,7,247,126,120,240,241,7,100,38,122,176,96,54,249,252,220,210,18,139,200,119,123,176,39,69,224,202,250,175,44,207,63,55,39,7,16,230,222,120,77,25,91,227,67,55,207,9,35,220,172,59,3,136,2,38,200,7,109,154,12,198,253,217,92,48,132,172,112,98,60,52,172,89,242,229,194,155,36,191,121,184,57,10,32,143,210,20,5,88,147,55,67,69,157,25,10,16,39,100,130,138,130,9,10,80,12,219,252,248,202,174,55,61,172,242,36,110,118,138,42,179,115,240,217,155,7,215,239,60,184,118,235,254,189,223,146,29,182,195,219,175,241,86,136,150,230,233,182,184,172,208,42,0,171,189,101,41,235,0,2,4,76,53,128,128,221,79,58,254,230,167,71,111,253,167,170,243,119,231,23,151,23,54,47,205,175,173,205,45,204,75,96,144,228,34,177,109,15,126,250,63,10,48,235,171,115,231,231,53,80,72,26,113,240,254,237,195,183,239,12,126,255,170,2,202,165,141,165,245,197,205,249,229,103,53,144,10,24,210,225,245,79,7,159,255,81,1,102,97,117,241,130,6,194,52,134,208,117,123,131,119,110,42,32,172,205,175,47,207,93,210,49,100,151,194,202,34,130,230,108,113,4,192,21,82,34,193,84,49,120,198,219,123,202,140,155,151,79,164,47,153,209,240,50,133,94,73,5,47,99,252,126,218,127,15,133,71,112,150,252,0,152,149,10,172,200,0,76,25,215,101,48,9,70,176,124,112,172,205,114,105,69,150,57,33,165,40,242,55,139,115,133,99,18,246,40,1,211,32,0,231,88,68,45,236,146,180,54,36,96,153,171,16,1,122,34,212,137,128,78,6,213,34,16,197,72,107,70,32,226,228,23,180,146,182,114,4,226,78,104,77,43,137,245,35,16,203,208,171,72,128,41,8,169,37,225,149,42,241,197,173,36,93,220,172,138,211,115,172,193,27,175,15,62,249,59,90,211,238,253,236,240,183,215,131,125,75,88,70,214,222,10,118,50,15,63,255,227,224,147,219,86,246,172,157,155,178,142,110,188,58,248,213,95,15,111,191,70,246,201,238,223,253,156,148,203,29,125,248,218,209,141,87,209,115,111,75,241,224,103,127,31,220,187,149,38,175,9,84,224,197,183,154,61,183,217,155,111,150,91,21,229,42,218,222,162,222,42,223,24,6,248,243,203,231,87,46,204,43,128,122,139,227,247,203,174,22,212,183,206,207,135,1,34,43,36,190,192,83,11,105,109,101,57,12,20,89,38,171,117,167,183,213,175,86,221,142,22,224,197,165,185,245,167,54,46,94,156,95,13,3,155,167,49,208,77,127,8,180,128,151,87,86,46,135,129,36,203,240,94,163,174,133,244,157,75,75,97,128,138,196,45,218,233,212,170,61,45,172,245,167,87,23,47,174,135,129,11,91,150,133,62,108,96,37,160,54,207,228,16,194,216,24,43,208,30,118,199,15,232,2,187,215,39,140,41,187,207,7,70,6,191,40,122,47,2,65,227,231,254,146,205,8,13,134,121,2,163,166,233,38,10,106,86,88,182,1,175,254,194,14,150,109,200,178,247,30,44,219,34,227,204,46,32,100,220,235,13,86,117,192,190,143,187,8,92,6,70,10,164,133,116,81,23,196,194,197,167,130,194,9,129,170,0,192,32,98,21,145,142,52,116,21,209,39,191,228,79,105,99,88,145,130,132,22,254,41,49,152,21,113,13,61,170,21,76,78,72,120,43,87,194,196,93,129,41,19,87,96,240,246,191,30,222,251,191,114,87,0,45,40,248,53,92,189,201,89,118,213,194,77,187,223,189,73,32,208,238,99,124,87,182,204,253,252,202,165,203,171,243,107,107,34,6,111,21,39,208,182,127,80,107,171,96,33,214,181,128,108,0,168,219,116,218,237,125,244,0,63,132,131,58,248,226,115,36,39,220,204,34,33,195,242,220,229,203,223,245,55,245,40,138,73,248,238,169,165,149,243,207,248,175,210,214,224,87,191,189,127,247,243,195,183,63,29,188,247,145,159,21,56,187,221,178,6,255,118,131,252,94,110,183,173,193,155,111,12,222,252,243,225,237,215,8,182,195,219,175,29,252,226,14,178,8,174,211,248,231,181,235,91,245,86,249,138,69,10,87,191,186,119,227,254,231,55,142,174,189,142,134,228,245,123,131,79,254,254,213,189,27,71,127,251,232,232,206,199,71,31,93,35,193,251,253,123,183,7,63,250,252,193,187,191,84,137,136,18,171,19,82,14,8,233,7,245,218,150,10,212,247,150,22,159,210,2,202,3,64,148,37,203,175,193,181,60,249,107,233,228,4,46,195,82,128,88,160,188,140,145,176,35,39,195,81,132,56,170,29,228,46,4,56,234,63,40,168,16,44,125,175,224,21,181,104,160,151,116,28,132,64,15,167,125,42,212,89,10,154,115,126,18,64,104,226,34,241,83,153,117,147,152,201,201,213,70,177,74,201,122,75,140,154,113,21,81,82,37,97,157,38,233,24,179,254,147,56,74,248,253,20,124,47,246,127,69,34,37,243,227,42,62,164,89,49,55,194,74,10,36,80,96,221,21,39,50,191,21,112,183,88,201,1,56,121,1,14,47,66,38,157,34,23,225,44,227,125,73,100,24,184,96,99,74,57,146,54,83,114,55,45,16,44,239,161,1,5,23,157,51,208,205,196,47,131,88,70,235,146,65,204,201,123,99,211,122,111,12,34,79,200,17,155,150,56,98,16,205,240,125,48,96,201,194,220,47,94,185,18,247,188,166,61,207,139,30,40,252,203,15,15,222,254,96,112,235,15,116,95,243,246,107,71,95,190,59,248,213,175,15,127,123,125,240,201,237,251,127,127,43,240,175,86,221,30,62,193,42,113,173,72,231,131,55,223,25,252,248,55,196,254,208,198,100,69,88,92,126,118,229,153,249,205,181,141,243,231,189,213,192,3,22,108,99,226,51,131,239,254,242,232,206,29,188,221,128,40,124,239,230,224,199,191,59,252,243,157,163,15,255,112,248,219,235,228,165,4,252,218,252,234,179,243,171,155,23,230,81,136,181,57,191,186,202,97,176,89,104,36,195,20,6,141,4,108,18,104,57,154,194,199,247,50,28,188,249,179,163,107,175,163,1,60,250,219,157,195,119,255,162,96,224,224,63,127,119,240,222,91,84,196,191,186,59,248,252,221,195,219,175,81,16,131,79,126,125,248,246,167,106,66,150,87,208,47,139,231,165,156,217,6,120,200,248,134,163,185,184,177,124,94,134,131,48,76,42,220,39,143,190,252,209,209,63,254,49,249,224,151,239,28,252,247,117,150,219,163,59,127,59,248,203,15,7,239,125,20,140,27,238,163,198,185,190,120,105,126,101,99,93,38,100,91,5,242,247,127,38,36,220,255,242,63,14,126,252,254,209,181,27,247,239,254,126,112,239,85,210,146,230,154,190,56,250,227,117,228,225,191,247,17,85,242,55,94,127,240,234,71,68,2,88,195,3,0,7,183,254,237,254,23,159,221,191,251,99,53,149,43,207,206,175,46,173,204,93,144,145,153,83,147,73,68,36,80,52,120,255,103,15,94,165,13,15,254,243,139,195,119,222,56,252,175,47,14,191,248,13,26,40,76,11,81,41,114,18,226,232,71,127,34,179,240,240,246,107,4,158,79,239,87,247,110,28,220,121,119,240,199,31,206,90,131,27,63,63,248,245,245,131,95,252,198,67,169,226,100,105,241,210,226,250,188,148,145,188,130,145,193,175,126,59,120,253,163,7,63,253,159,163,191,209,225,60,248,249,103,15,126,254,215,163,107,55,194,70,247,226,198,210,210,230,210,226,242,51,186,113,46,112,115,19,203,34,108,110,174,125,119,109,125,254,146,4,92,158,155,15,15,222,250,235,193,127,188,58,120,255,47,71,127,253,32,12,232,220,198,250,211,18,144,5,14,36,21,209,173,31,30,252,251,167,104,120,126,252,209,193,111,127,247,224,79,55,204,144,60,59,183,180,120,97,110,93,54,151,139,54,152,103,138,153,53,248,228,247,7,111,254,13,81,129,167,184,114,4,206,47,45,206,47,175,123,118,87,45,126,59,107,43,16,196,25,119,138,213,100,220,237,44,153,57,135,255,248,201,225,23,239,33,83,245,250,127,177,60,7,172,226,195,54,74,193,82,164,231,87,150,151,231,207,75,81,81,35,73,107,250,116,168,66,86,6,138,74,185,50,216,212,106,5,164,235,215,45,10,79,189,110,121,230,5,216,43,106,121,101,108,72,180,228,100,89,33,202,175,218,10,217,188,25,130,156,140,204,236,83,50,53,102,223,166,102,139,172,249,90,149,122,112,237,173,90,27,250,6,106,132,171,43,27,235,200,241,16,209,229,57,189,34,179,38,12,222,242,252,250,115,43,171,207,200,0,22,56,128,131,159,222,28,124,254,110,100,163,70,17,105,140,154,77,173,218,253,187,63,62,184,123,247,254,221,47,16,232,159,125,60,184,119,141,76,107,164,63,183,222,25,188,117,115,112,235,103,7,159,189,73,134,51,116,174,207,45,159,159,95,146,107,80,137,159,130,119,190,24,220,250,153,133,79,72,88,161,35,48,63,119,129,134,139,18,208,83,188,179,69,142,93,130,177,72,91,71,119,254,120,248,197,27,190,46,60,120,239,218,209,31,175,99,69,70,74,120,244,229,143,14,63,250,215,251,119,63,30,188,113,243,224,247,255,117,248,206,27,178,149,130,196,188,158,91,166,28,196,92,86,74,207,253,123,191,61,250,159,159,198,167,7,65,196,51,250,171,123,183,209,76,199,117,71,71,95,254,104,240,254,135,135,31,191,21,74,239,165,181,133,205,249,239,156,159,159,191,64,230,185,212,183,147,11,50,196,45,103,208,168,189,115,222,6,251,192,195,130,8,6,190,210,38,231,168,77,230,136,31,188,241,203,161,169,192,115,171,139,104,110,45,95,8,50,37,188,243,102,27,2,65,54,237,226,210,202,115,82,15,48,103,8,4,159,29,193,16,36,148,228,13,129,64,215,64,0,82,144,137,248,232,206,23,67,19,49,158,248,80,194,28,69,197,112,1,99,16,80,52,60,136,112,241,18,42,46,93,94,255,174,2,68,184,112,49,8,141,187,93,44,72,103,199,144,108,88,232,66,148,207,74,103,235,195,178,97,148,94,3,27,150,183,85,102,198,192,198,132,249,145,249,99,218,176,48,191,50,79,109,24,7,127,40,54,140,210,18,106,195,242,58,27,198,0,209,216,176,188,206,134,49,64,52,54,44,175,179,97,12,16,141,13,203,231,165,19,109,40,54,12,58,47,106,27,150,215,217,48,8,66,109,195,242,58,27,198,80,161,180,97,121,157,13,131,32,212,54,44,95,244,150,135,63,29,252,226,237,195,223,125,130,162,18,213,140,160,17,240,198,242,51,203,43,207,45,75,160,205,204,204,152,67,163,116,170,161,217,217,108,216,33,46,218,152,217,210,242,144,24,94,91,198,166,83,253,226,92,203,47,149,229,92,24,191,66,151,107,17,24,32,2,3,3,57,163,204,61,146,70,57,73,35,47,115,72,16,137,96,192,96,146,38,34,16,24,109,209,171,216,132,54,32,112,36,77,10,66,19,105,238,129,108,220,137,100,5,105,36,178,127,39,182,240,114,66,100,239,78,124,15,35,31,34,158,108,80,38,173,76,194,208,150,57,190,165,154,120,219,22,192,130,132,7,29,24,161,9,63,190,57,1,35,167,35,54,22,250,25,69,176,78,155,20,248,38,194,208,217,121,129,148,32,182,37,45,10,66,11,224,36,144,38,69,161,137,40,237,146,40,22,16,27,146,54,83,34,49,76,152,71,84,9,140,155,50,0,163,234,173,106,41,115,27,168,186,171,186,112,35,148,3,35,164,138,71,232,228,80,65,244,23,90,218,78,5,80,92,75,105,135,188,182,131,191,56,208,214,5,109,107,97,222,23,85,100,123,139,23,109,166,162,154,93,160,104,99,21,197,236,82,68,27,171,8,230,23,29,98,51,68,173,80,104,107,94,212,10,141,51,73,186,136,90,33,159,183,121,81,43,228,211,55,47,106,5,239,126,209,118,42,128,10,173,200,139,90,33,247,166,104,107,65,200,42,183,137,180,23,181,130,115,105,104,51,21,213,18,173,200,139,90,33,117,80,104,99,21,193,82,173,152,153,153,153,229,150,98,224,17,80,227,158,229,47,117,224,154,188,194,174,252,225,21,26,220,162,47,94,144,195,95,146,35,24,14,73,23,91,104,15,116,79,210,62,39,180,103,61,4,190,139,45,34,0,222,130,140,32,17,3,20,191,216,35,39,98,96,214,35,161,71,78,196,0,215,56,9,134,188,208,65,190,80,251,149,197,5,161,3,240,52,36,76,231,69,30,124,199,67,58,206,5,177,3,179,54,10,157,138,160,131,218,45,129,37,61,89,177,135,158,107,59,155,19,122,64,31,69,100,196,182,69,28,122,245,179,115,98,143,16,5,207,137,84,233,135,219,134,227,45,243,112,132,46,54,28,112,209,223,145,81,149,23,249,128,43,138,132,170,130,216,67,63,228,182,100,204,25,231,72,236,81,18,123,112,174,18,215,199,158,18,175,220,146,184,77,160,87,46,171,236,33,93,40,103,173,156,173,236,161,80,150,92,78,217,67,161,44,185,156,120,47,152,224,79,49,188,231,242,74,28,146,53,20,127,230,35,31,130,35,88,192,102,61,28,226,85,100,74,247,106,150,244,40,168,122,248,75,41,59,132,185,162,146,15,110,85,245,173,91,81,201,7,183,180,6,61,148,124,8,235,43,61,82,89,20,249,208,79,147,188,68,175,116,14,216,172,149,151,232,149,222,8,229,37,122,165,55,66,121,137,94,9,30,25,51,32,121,137,94,169,125,179,89,220,35,4,135,48,132,121,137,94,41,29,180,89,210,67,57,30,10,189,202,75,244,74,238,173,205,250,61,148,124,40,244,42,47,209,43,149,223,54,75,123,0,62,36,174,155,104,119,103,102,102,4,28,250,30,200,245,147,213,141,82,79,143,45,25,245,50,71,124,181,168,215,56,188,80,212,7,59,202,26,81,31,105,242,229,161,51,186,242,80,31,111,66,149,161,51,66,101,168,143,97,216,69,161,94,26,80,95,15,202,40,77,226,165,160,51,226,181,126,135,183,95,59,248,239,235,7,111,127,56,184,251,225,224,253,191,146,157,19,190,16,148,189,210,151,126,154,11,81,128,191,17,230,207,4,225,131,141,107,228,19,98,254,167,194,184,86,107,193,39,196,152,79,133,89,240,75,114,240,19,98,56,113,91,107,214,122,180,94,228,245,87,239,127,249,187,131,235,119,82,99,171,238,75,125,183,75,200,123,146,37,25,190,122,209,251,34,201,236,25,36,204,110,218,78,183,218,189,116,211,105,184,231,58,164,221,102,195,237,57,233,239,119,91,77,239,9,234,153,198,29,243,103,240,201,219,217,51,76,219,86,163,214,115,27,237,222,254,153,23,125,2,105,125,5,36,176,219,110,53,201,141,194,34,133,224,157,64,98,14,146,72,26,50,52,6,125,5,34,97,107,158,202,195,119,255,114,240,246,7,7,239,126,118,248,231,59,131,159,252,248,240,55,31,12,110,253,228,193,181,235,232,207,55,255,99,240,225,191,226,195,213,248,201,159,126,62,184,245,135,193,251,31,14,62,189,149,26,67,4,63,87,107,86,90,87,209,240,89,125,28,181,66,170,119,157,78,173,217,75,231,3,178,145,64,54,175,226,62,155,72,23,8,229,53,6,16,71,187,208,133,39,159,104,0,185,44,26,30,247,246,174,242,245,119,4,233,151,225,38,191,95,118,39,17,236,52,61,22,70,190,139,131,183,108,94,255,219,253,127,252,20,159,34,127,123,93,118,36,110,112,231,239,131,207,223,77,141,209,23,216,230,40,249,46,4,124,151,73,123,252,117,73,194,115,57,128,192,49,204,180,213,49,235,159,207,34,199,217,200,241,118,134,223,237,31,212,218,147,228,192,209,100,38,147,73,243,231,224,20,76,7,133,232,28,191,88,16,104,133,81,242,92,20,121,118,105,39,134,111,15,146,130,119,191,15,228,31,216,235,39,69,91,52,97,173,186,93,151,126,189,242,201,61,235,156,196,94,189,76,190,79,9,141,10,255,121,202,70,13,45,198,242,213,3,124,154,18,181,236,178,223,34,252,14,99,235,86,170,224,187,62,151,91,248,123,140,120,53,69,29,51,107,104,213,0,95,211,27,111,212,38,144,227,16,198,162,217,74,239,211,225,45,246,96,45,149,130,197,151,170,209,94,72,128,97,100,224,246,171,100,217,227,215,73,10,6,145,102,44,75,205,152,60,241,132,181,7,191,52,26,91,234,181,170,213,232,102,150,90,78,5,202,125,194,58,23,192,86,143,12,254,40,37,149,116,163,139,83,120,222,95,53,143,0,95,208,218,155,47,61,33,102,160,12,53,174,128,84,254,67,250,224,139,118,204,23,92,184,126,178,23,191,242,139,43,249,126,236,158,248,133,88,107,47,3,218,65,57,146,207,35,26,144,16,44,114,50,26,192,242,169,39,34,104,24,131,10,118,229,27,159,240,236,161,14,37,219,7,34,205,154,160,4,43,142,25,62,208,33,46,50,207,72,71,66,232,117,18,144,50,206,38,246,140,222,255,235,225,237,215,120,7,78,226,106,66,213,122,184,30,231,253,187,95,28,125,250,42,173,78,187,253,218,224,157,155,135,31,126,202,125,252,236,254,93,228,48,145,235,103,14,126,123,111,112,239,22,253,196,245,224,243,119,15,223,253,104,240,206,205,12,1,128,126,107,111,129,211,64,239,220,76,91,133,131,79,254,59,53,118,222,169,215,221,142,247,129,120,157,175,90,198,45,249,101,148,60,20,156,135,223,255,25,82,79,74,147,13,121,248,234,222,13,83,38,158,207,208,99,71,239,220,124,129,120,24,111,221,68,108,29,252,226,206,224,203,215,31,252,238,139,131,247,222,250,234,222,13,218,232,214,157,7,215,222,250,231,181,31,82,166,93,37,211,57,142,105,193,111,34,15,5,166,201,249,52,143,105,159,52,242,146,25,165,73,250,105,196,204,154,207,203,225,135,159,78,130,46,23,209,196,81,17,8,252,92,52,193,56,242,240,35,158,56,122,23,17,214,124,114,193,159,127,223,159,224,190,250,119,225,253,243,218,117,114,183,222,21,119,255,159,215,174,147,59,233,254,121,237,58,57,241,242,207,107,215,253,251,238,254,121,237,58,185,111,238,240,195,79,15,63,126,11,193,254,237,143,142,238,188,33,245,251,192,37,80,158,219,7,239,20,51,113,115,27,164,61,112,115,27,1,4,78,30,76,91,185,92,124,137,16,1,93,113,247,207,226,205,178,193,157,191,127,117,239,6,185,11,106,240,230,27,247,239,190,255,224,213,143,6,111,18,182,236,131,95,220,241,207,55,30,253,241,58,7,228,171,123,55,174,184,251,100,238,14,62,254,249,209,31,175,223,255,226,3,124,247,193,224,222,181,193,251,127,197,48,114,7,191,184,67,191,71,163,128,65,223,222,186,115,255,139,15,142,126,244,167,163,223,221,56,250,228,127,14,255,241,9,161,254,191,62,58,120,13,207,122,167,217,221,172,53,171,45,114,145,35,100,224,254,189,219,254,33,27,2,222,135,122,116,231,111,71,159,126,116,240,250,219,196,73,255,234,30,62,80,225,52,187,200,31,129,219,132,42,69,44,166,59,110,155,140,72,64,2,25,143,158,7,135,27,13,208,46,24,11,203,3,188,121,197,221,151,216,158,43,238,190,15,198,111,186,235,212,37,51,22,179,237,53,214,185,242,192,214,135,121,244,160,105,82,142,189,61,122,199,158,97,56,113,255,158,129,110,238,230,139,221,18,242,246,237,211,231,237,3,89,198,116,250,153,209,24,210,87,197,76,20,1,121,134,216,179,24,159,240,22,65,173,67,136,219,154,187,215,82,92,110,4,92,110,124,92,104,97,55,195,132,90,198,199,3,86,84,51,175,26,116,48,117,227,121,156,254,218,49,62,33,89,61,116,200,253,158,18,134,21,238,60,159,238,148,186,243,32,74,123,184,254,124,112,232,217,243,24,252,26,96,255,46,4,169,179,68,179,243,158,163,180,234,246,44,149,127,196,36,150,123,66,102,182,167,240,88,15,191,248,233,193,175,223,35,82,60,184,117,235,232,203,79,233,93,198,127,57,250,235,7,200,147,251,249,103,131,107,191,196,73,188,249,78,167,213,185,212,221,54,113,157,93,212,22,217,99,226,15,184,180,43,71,86,208,202,44,1,7,135,52,124,217,14,218,38,181,110,231,30,198,186,13,89,30,194,194,13,193,71,89,185,133,126,9,45,221,185,211,184,116,7,194,140,189,118,195,241,24,210,231,185,140,116,1,103,207,144,22,132,47,58,171,110,207,124,177,225,112,120,198,200,108,53,245,90,135,45,48,220,230,164,191,190,200,247,39,225,167,64,31,242,10,51,248,253,175,7,63,70,161,35,187,119,22,100,2,23,155,229,142,219,112,155,61,117,132,13,86,16,176,17,182,89,243,122,18,83,126,85,4,201,89,117,121,231,112,11,15,197,169,179,238,176,93,82,150,61,63,90,203,206,178,154,168,85,103,65,155,89,116,73,159,132,172,121,254,116,89,115,40,200,24,150,156,29,135,33,125,128,44,116,252,23,220,158,196,110,152,197,17,146,142,250,12,253,225,237,215,240,247,0,195,171,65,252,239,35,63,108,83,75,190,75,233,125,27,5,127,190,26,61,185,127,247,218,225,159,239,124,117,239,198,209,151,191,56,248,197,157,193,235,31,61,120,245,35,239,227,147,220,7,43,245,214,183,140,26,195,77,124,175,51,159,138,14,218,241,206,61,126,197,198,22,247,191,248,195,209,239,36,17,136,62,172,200,69,13,43,48,102,54,158,208,197,12,32,155,221,16,226,3,62,50,120,156,203,126,36,115,217,143,88,214,25,143,6,222,204,81,69,249,228,150,101,34,143,247,62,34,249,119,252,165,248,27,68,217,200,53,135,131,127,163,183,227,124,117,239,70,150,206,94,252,130,124,49,127,240,201,171,228,33,105,68,118,141,116,83,185,196,110,28,109,162,217,139,229,86,37,29,37,59,73,155,252,12,151,175,31,190,105,214,185,109,126,163,164,124,182,194,104,125,54,192,100,162,14,27,128,107,230,173,241,29,18,114,213,10,167,203,85,243,165,24,195,79,3,35,48,164,207,66,234,135,125,193,237,249,14,133,81,164,237,183,54,137,183,89,68,9,7,243,44,112,227,0,94,30,187,135,195,31,114,30,156,197,54,156,12,120,40,90,106,247,141,70,137,182,149,249,228,52,73,141,11,51,208,170,142,221,111,154,228,199,83,164,220,170,63,108,215,27,126,52,89,230,144,193,207,182,122,30,153,247,33,96,147,188,199,46,105,203,173,132,222,83,121,149,44,255,197,86,88,25,123,240,203,79,30,92,187,29,124,146,149,249,146,170,172,40,150,126,251,209,47,136,245,62,25,170,36,158,43,87,129,81,3,237,43,169,95,209,21,253,14,222,189,115,255,238,181,90,197,47,113,95,172,24,213,92,123,21,234,181,10,83,203,190,88,81,84,178,215,42,26,121,130,235,64,137,216,238,255,227,38,50,247,235,181,134,219,234,107,114,88,192,179,238,145,182,188,47,72,159,242,184,79,72,201,85,241,52,150,92,149,78,122,201,213,212,233,44,185,154,126,28,166,198,14,83,103,190,22,97,234,137,61,212,98,103,79,225,169,22,219,30,226,177,22,68,173,211,235,57,229,157,134,219,236,121,27,68,115,254,19,253,225,42,27,232,81,0,5,28,174,114,24,64,28,97,124,15,85,70,129,243,54,197,108,2,215,32,169,76,66,113,20,153,4,129,185,4,178,8,2,76,93,6,65,222,56,161,236,65,241,52,100,15,56,9,26,103,14,4,201,15,233,171,238,234,161,94,112,123,52,14,50,139,131,105,99,117,12,44,195,224,69,43,134,7,57,104,235,104,56,252,160,196,12,137,223,60,26,22,26,103,152,225,160,141,163,203,42,185,10,71,37,134,196,234,26,101,24,146,171,102,148,65,31,78,238,70,58,218,195,205,219,72,7,103,40,231,172,52,152,146,61,100,165,197,200,250,20,102,8,217,62,178,244,20,173,248,228,211,83,164,44,232,113,126,234,113,126,106,84,249,169,225,150,241,22,162,238,183,159,196,157,198,98,2,59,141,195,41,81,46,37,83,162,252,168,100,120,166,134,156,225,25,252,234,215,7,255,241,129,42,207,67,174,5,49,72,246,72,129,69,207,247,168,192,36,148,242,153,254,90,164,124,200,58,234,167,124,200,247,4,30,122,190,103,102,8,233,30,200,233,137,76,247,72,114,92,167,44,221,195,122,111,178,124,15,219,34,169,132,79,105,52,9,31,158,189,68,50,62,60,80,125,202,71,218,58,161,156,79,233,116,228,124,88,17,70,72,250,240,178,79,60,235,83,10,83,184,33,164,125,36,40,146,207,251,72,144,12,35,241,35,69,147,64,185,139,20,114,18,101,26,122,12,137,157,137,209,163,25,86,98,70,130,106,232,153,25,153,54,15,41,53,163,70,53,180,220,140,4,229,16,146,51,187,78,199,186,40,177,89,236,226,130,90,4,6,144,244,210,89,58,235,28,85,226,151,83,99,217,189,172,147,182,178,123,217,42,250,57,85,192,63,115,248,103,22,253,44,229,209,207,156,254,173,27,60,33,111,75,94,123,132,128,252,97,227,23,217,130,22,16,126,50,51,133,91,146,246,78,208,183,40,235,133,16,20,243,60,208,82,17,255,180,241,207,10,250,89,152,193,191,99,74,75,51,65,251,66,37,104,79,158,144,94,4,101,33,151,6,34,42,243,8,166,112,211,169,34,120,2,72,41,86,3,244,18,4,211,24,166,141,17,228,178,244,15,36,4,242,98,11,253,204,99,100,118,21,72,89,59,6,67,17,81,49,140,99,132,64,47,77,2,130,240,100,46,64,31,90,128,128,25,156,98,160,33,217,138,0,58,15,132,80,13,56,35,207,73,27,127,132,176,154,170,134,8,3,213,143,16,121,171,25,33,60,200,234,33,178,142,61,66,128,3,3,198,67,198,73,84,116,58,200,177,128,146,209,162,66,35,243,57,27,112,224,115,19,12,50,25,150,169,41,161,81,33,64,79,222,210,150,121,32,16,39,32,130,142,95,158,142,16,158,201,112,0,43,128,101,87,66,81,32,95,19,82,136,136,36,84,16,246,109,160,172,229,96,216,25,97,22,192,176,131,39,69,104,77,167,102,192,240,66,54,11,10,53,133,92,110,133,32,198,28,64,204,68,29,69,148,132,167,25,97,72,195,120,226,7,25,50,203,116,46,8,18,159,2,188,22,149,188,98,99,71,152,173,70,147,114,193,140,20,44,34,76,11,89,173,166,113,35,102,181,154,73,31,103,158,35,4,177,77,177,201,186,134,16,216,37,160,142,37,192,50,161,162,12,126,22,3,74,253,53,75,46,253,114,58,176,69,17,128,146,159,81,8,10,140,93,136,137,46,3,221,55,32,200,87,110,44,34,48,164,100,114,149,74,64,226,64,79,56,59,163,35,194,131,131,231,129,8,72,101,42,42,194,32,67,62,166,210,220,138,150,156,169,80,35,14,230,1,197,172,53,21,68,29,41,79,142,48,3,236,52,183,162,20,171,192,154,82,17,145,1,172,166,229,102,32,159,150,175,204,110,90,181,50,99,4,97,206,211,113,86,230,192,22,29,103,198,138,196,249,226,194,131,156,23,240,3,65,21,4,51,71,249,155,1,67,61,163,28,143,112,4,54,30,204,124,25,12,175,154,94,75,128,134,199,192,152,94,106,42,178,0,25,81,199,45,32,186,153,180,129,119,13,217,87,129,32,200,10,0,25,121,91,74,67,19,2,102,114,84,139,36,3,199,41,72,222,33,214,20,119,200,67,243,75,166,213,86,64,29,25,137,24,74,140,199,192,60,2,136,238,94,98,4,182,110,0,25,95,179,144,14,95,106,138,204,248,225,49,16,65,16,100,64,68,100,216,225,226,195,132,171,36,202,4,81,27,229,105,138,172,7,230,3,59,29,142,166,32,34,160,67,10,166,18,89,20,143,101,151,74,105,126,201,36,254,76,1,206,76,48,3,244,78,124,30,186,57,164,141,231,26,7,174,99,84,55,157,74,28,234,158,160,20,76,140,6,205,67,136,158,128,21,205,206,167,245,81,5,214,162,169,64,178,34,165,133,48,26,45,25,137,52,171,81,1,51,153,74,48,127,236,225,37,132,150,33,7,198,17,153,45,172,201,37,22,156,37,68,203,129,251,174,244,45,76,102,236,140,18,89,48,200,122,127,34,130,9,97,39,44,158,104,50,27,34,7,161,90,112,216,217,11,125,64,197,130,83,230,145,73,64,152,121,127,96,144,213,238,159,110,132,194,188,63,172,166,97,238,31,143,88,239,253,77,49,154,6,180,72,237,254,241,179,52,138,247,135,16,228,65,214,33,118,234,76,53,13,131,21,77,58,15,245,203,161,245,53,241,236,136,238,131,24,159,174,107,138,40,168,88,21,68,196,204,195,146,66,237,224,52,156,210,34,96,167,39,94,147,143,231,125,234,69,26,120,21,177,189,79,57,199,222,8,225,137,118,60,239,211,210,58,159,66,198,43,186,247,105,169,157,79,23,114,0,119,17,204,99,158,162,108,207,192,255,157,230,77,233,31,101,32,22,144,75,36,58,51,85,2,8,114,105,206,219,128,126,42,55,54,218,164,96,84,208,50,135,51,136,50,197,172,131,145,185,86,57,156,140,185,158,14,166,137,4,141,126,41,21,67,115,118,252,248,8,71,178,199,65,68,1,103,187,42,25,2,197,59,67,145,129,220,181,62,66,134,104,84,138,0,179,117,112,255,128,170,151,232,31,152,36,67,212,160,129,227,37,250,13,199,73,178,177,41,78,224,182,68,204,105,25,38,217,176,136,84,9,49,189,1,55,35,8,184,239,80,249,162,38,217,166,148,68,128,204,175,30,80,220,36,27,240,77,77,230,237,180,129,94,109,9,106,122,44,55,11,90,98,89,146,13,164,247,205,221,172,153,116,120,146,141,204,33,87,240,236,36,110,214,241,214,6,176,30,192,20,125,57,173,119,167,204,151,126,129,3,51,119,42,20,129,175,117,252,126,114,140,109,32,157,214,57,170,0,36,202,54,16,143,152,69,9,178,239,132,169,232,219,64,252,250,193,78,82,48,200,250,109,160,173,116,248,20,147,237,2,129,253,100,129,34,195,109,32,139,139,218,96,132,83,5,241,1,29,46,224,245,83,160,100,197,86,164,12,66,247,53,177,22,149,13,216,119,3,196,145,72,1,27,117,42,42,30,103,126,31,98,230,183,2,12,50,156,122,145,82,181,120,201,12,115,193,173,99,120,224,96,15,71,237,130,135,59,94,106,15,28,152,10,181,11,174,114,73,76,108,106,48,6,33,148,198,245,192,113,24,27,230,130,235,150,201,48,15,92,27,225,204,68,67,38,241,192,179,112,69,211,103,226,84,158,118,88,34,46,216,141,141,157,141,224,73,81,122,215,113,179,17,250,253,6,144,74,48,219,112,136,230,117,79,195,16,202,108,195,33,170,35,12,50,94,81,243,141,42,151,157,245,72,130,93,168,4,242,141,208,116,59,64,139,142,149,111,132,14,189,204,17,198,90,68,20,203,36,223,24,197,80,19,119,24,112,96,96,168,99,184,195,129,53,61,102,118,49,28,65,130,85,81,10,223,84,140,94,146,112,135,241,146,169,85,190,99,186,195,252,54,87,132,170,40,199,128,215,42,76,72,37,87,21,5,141,10,158,7,172,63,108,37,234,14,227,121,32,214,249,37,231,14,243,182,136,161,37,9,119,248,184,233,253,80,119,56,40,255,49,204,69,71,117,135,49,130,40,185,232,168,238,48,239,93,43,115,209,68,238,208,49,208,214,223,209,205,24,166,128,9,184,136,148,217,98,0,206,182,3,112,132,94,226,50,23,192,202,81,0,115,133,108,185,23,8,130,34,121,4,156,64,218,1,15,108,1,254,94,4,67,154,85,144,146,101,72,9,220,119,134,150,10,197,239,111,188,17,29,131,109,138,37,208,134,16,87,228,137,216,202,2,199,139,72,185,144,149,139,69,34,101,48,173,224,20,35,194,97,19,82,96,162,133,100,170,11,74,81,72,71,165,72,212,148,202,215,6,77,103,128,184,74,193,115,42,144,138,241,120,216,96,61,80,82,145,231,41,165,122,2,144,105,72,193,28,64,90,128,214,207,56,193,147,216,37,5,194,94,38,59,68,86,148,17,34,38,15,58,94,69,88,6,39,29,34,75,61,66,18,233,3,208,126,117,140,22,193,241,164,79,218,99,4,164,209,12,160,23,216,25,56,54,26,74,85,106,146,26,75,136,82,222,34,217,64,68,228,15,74,41,220,21,0,131,6,139,200,34,137,52,64,16,153,210,18,224,181,8,104,135,189,72,0,66,202,221,108,224,130,139,49,151,61,53,122,14,136,201,195,118,180,0,16,48,211,150,140,1,181,163,48,109,19,125,198,90,138,226,3,176,205,5,3,7,189,77,141,178,210,69,84,83,19,177,176,150,53,72,37,152,172,186,230,164,48,131,12,169,16,103,47,25,161,156,98,213,149,140,16,155,63,3,169,101,176,210,70,216,61,134,17,81,69,34,3,172,166,80,8,32,237,71,165,92,0,191,3,34,242,54,47,119,137,239,84,134,17,142,184,172,199,219,97,102,43,4,12,150,76,237,170,192,104,23,112,97,200,79,47,33,5,21,43,162,223,32,186,101,228,0,16,37,101,6,174,7,106,42,56,141,114,236,52,183,86,103,171,74,189,194,131,156,80,50,132,137,18,188,209,210,45,153,82,103,214,146,249,178,146,57,236,197,125,216,117,20,230,167,10,25,25,88,138,18,46,177,160,124,148,177,187,240,84,35,227,234,10,158,146,184,243,13,79,147,42,53,16,138,200,95,131,120,187,207,82,100,133,18,4,23,93,7,26,187,48,255,32,48,103,194,24,20,224,156,0,243,166,88,130,106,26,149,82,152,208,84,175,16,138,0,100,42,224,131,14,102,33,166,208,130,218,22,113,219,193,46,24,12,163,96,234,161,81,97,188,235,120,130,178,129,29,221,2,81,169,95,34,109,96,77,143,151,133,49,174,152,141,24,210,250,235,10,22,145,98,97,129,10,71,231,135,96,66,36,70,34,234,122,80,0,94,19,51,90,102,232,131,29,144,152,235,129,3,20,1,172,13,62,17,32,202,212,11,129,53,0,209,226,3,106,138,203,129,58,22,129,159,92,132,230,26,120,212,197,156,145,184,132,40,51,127,12,113,193,220,134,167,75,192,22,153,235,76,65,169,51,6,126,17,158,141,116,62,151,99,169,44,156,61,37,104,174,205,22,16,244,100,58,205,155,66,56,212,44,65,1,7,74,138,200,102,16,38,162,74,2,110,91,62,54,82,99,3,54,75,43,193,107,201,161,121,24,146,168,204,9,204,114,123,230,39,25,175,130,241,172,224,218,151,133,107,178,96,162,37,118,38,226,162,95,32,53,94,69,39,24,46,106,5,213,20,89,161,4,65,195,51,13,181,200,124,253,130,142,112,22,252,20,221,225,42,112,29,141,168,203,69,22,87,48,147,169,160,202,64,187,115,199,22,87,30,110,247,86,1,69,91,137,137,43,86,24,27,133,15,60,200,208,120,197,202,176,104,248,0,214,52,7,198,0,210,187,117,124,14,224,116,143,152,97,161,243,153,196,151,112,86,123,233,20,62,219,34,201,167,68,213,156,18,67,46,152,104,199,161,87,45,94,33,8,140,74,47,217,23,199,40,43,196,140,195,50,144,45,173,235,40,86,31,20,88,183,144,55,215,96,63,206,15,203,180,230,26,68,97,116,183,160,26,232,21,28,45,202,89,17,72,194,115,212,192,68,83,153,232,40,94,144,197,57,244,52,0,81,121,59,112,193,81,44,171,112,5,166,125,97,204,108,67,91,116,60,74,45,5,161,129,227,165,119,73,66,40,133,102,28,104,145,61,99,188,65,17,74,169,197,122,118,69,102,144,97,183,25,70,7,194,105,223,10,81,135,240,244,126,84,218,169,21,18,29,175,16,74,97,1,92,20,131,40,100,29,181,148,194,184,30,26,199,2,200,141,113,14,36,16,17,160,215,134,6,0,30,43,158,142,172,190,218,137,86,149,115,195,88,77,59,80,104,169,144,241,68,203,6,227,126,156,196,190,84,200,64,68,192,226,51,82,6,251,57,112,35,66,175,20,54,83,246,0,130,236,156,113,6,219,72,125,75,194,126,50,19,213,64,110,136,166,111,69,214,40,62,70,147,48,11,115,49,209,13,34,200,182,232,103,0,233,54,3,126,135,163,82,49,209,162,106,58,153,172,81,136,22,217,105,110,78,210,144,79,43,198,28,172,171,96,39,102,146,230,90,220,229,47,144,245,128,219,28,52,52,212,121,144,19,32,69,200,148,106,151,17,169,34,41,152,23,212,20,38,43,225,68,11,243,60,64,0,18,221,82,74,57,99,202,183,224,46,148,201,28,142,192,153,183,236,224,49,24,206,28,182,56,175,66,194,236,49,236,171,207,107,106,44,148,89,33,93,6,55,84,10,249,144,177,9,102,50,115,26,57,162,205,209,140,13,152,104,198,121,33,189,22,49,213,82,145,211,251,230,90,84,0,243,32,38,165,142,145,10,28,123,38,135,45,177,129,45,10,161,23,186,136,81,28,25,32,34,19,122,163,59,50,186,137,54,165,114,23,163,168,67,248,68,99,182,126,139,105,222,164,231,66,196,139,16,76,147,228,170,173,144,114,20,195,96,48,209,224,190,42,121,62,5,56,32,220,108,133,43,197,116,37,45,196,104,149,8,186,97,174,202,192,249,181,133,14,177,150,82,122,197,173,39,240,212,216,208,104,183,130,226,25,59,205,27,56,232,76,26,59,188,112,35,219,79,211,1,99,103,144,223,50,167,221,79,161,0,14,100,233,36,75,147,77,82,241,177,37,140,65,14,108,50,112,94,141,148,143,8,5,40,230,206,111,236,249,17,248,166,132,193,242,12,63,80,57,48,171,115,209,235,164,64,174,66,198,32,207,141,138,191,10,104,63,197,240,129,57,152,22,20,84,84,77,237,194,18,98,236,42,130,177,99,156,89,89,205,141,249,176,131,236,123,84,177,152,249,31,186,5,167,82,73,128,51,62,0,73,96,192,217,68,92,176,159,108,238,176,84,92,129,51,184,241,85,22,212,244,152,115,85,207,25,8,64,132,82,7,213,26,64,7,182,16,240,228,78,9,60,121,222,109,144,74,72,208,254,8,28,168,162,70,19,158,84,158,146,183,71,13,138,6,166,194,135,215,157,22,68,1,242,213,68,137,195,182,123,147,27,222,96,162,25,137,2,174,101,34,2,189,45,114,69,19,13,246,85,115,198,185,138,132,109,145,9,223,94,81,241,177,131,111,215,17,100,144,5,243,192,124,223,47,233,121,32,2,82,133,139,96,86,87,37,94,5,216,87,53,79,10,38,236,85,132,112,163,86,226,240,164,96,181,44,12,96,20,142,163,237,198,70,80,226,16,215,17,230,18,97,85,139,80,79,39,225,184,34,14,50,60,130,39,112,115,34,6,89,147,65,10,82,203,38,51,182,42,174,198,97,142,115,124,115,29,33,70,75,42,178,116,200,240,230,210,208,113,6,73,193,184,39,12,244,252,25,164,212,212,158,179,101,224,56,131,172,99,116,207,217,202,238,109,77,9,98,97,221,75,211,220,117,236,97,15,6,57,217,204,93,217,166,156,5,169,132,4,99,2,200,89,196,132,84,244,45,108,33,8,204,9,131,166,246,156,77,56,211,5,129,17,226,122,181,135,161,168,20,4,107,108,121,75,224,9,228,133,67,29,231,88,229,63,81,120,10,102,114,12,207,217,50,112,156,131,228,120,185,44,136,34,204,115,54,81,92,190,58,39,193,225,85,204,131,40,158,51,226,91,52,209,172,227,252,144,108,145,161,231,172,90,135,173,72,187,177,101,87,16,66,54,109,94,48,55,180,121,96,228,120,9,179,186,82,21,184,9,115,35,71,226,85,196,246,156,67,149,216,165,117,118,81,88,142,170,196,66,149,90,148,1,148,115,204,58,206,96,162,25,120,206,174,45,12,114,152,227,124,2,6,249,152,251,204,129,185,118,133,213,56,242,70,139,108,119,60,53,38,45,204,131,19,109,11,252,14,44,21,119,144,65,62,102,164,44,58,59,21,159,234,8,106,154,24,213,224,242,33,250,25,191,18,176,142,57,120,83,41,6,68,106,226,115,138,115,56,180,37,120,66,47,247,135,23,195,68,250,52,162,255,123,14,220,151,195,92,71,66,16,123,79,2,4,37,128,89,228,128,254,172,6,32,72,17,107,86,239,235,69,189,94,136,212,202,146,217,171,191,233,136,28,85,244,238,249,37,160,139,65,211,144,111,75,234,223,178,231,24,0,2,45,237,20,40,1,148,11,158,208,67,149,85,37,226,84,112,119,14,145,105,41,124,120,243,249,180,247,41,207,241,212,152,238,187,156,43,205,178,107,117,247,155,229,12,250,77,223,246,130,211,115,172,115,218,207,124,166,38,232,23,75,195,191,122,12,62,106,27,70,96,230,66,107,28,65,37,159,18,55,161,17,126,150,218,251,170,59,70,27,214,119,34,53,246,202,132,209,183,155,81,107,79,200,210,118,110,179,223,192,95,214,182,206,89,13,231,138,59,254,252,11,1,89,243,205,126,99,177,89,109,165,45,59,59,161,134,225,125,156,91,6,2,124,27,59,109,217,182,6,202,118,203,3,130,63,52,237,118,170,78,217,125,249,149,151,83,99,227,235,157,118,249,146,179,93,43,79,140,103,39,210,150,236,223,228,164,149,157,181,16,184,140,223,154,246,68,50,184,216,113,26,248,99,192,34,132,201,73,203,6,61,153,214,20,194,90,175,227,58,13,37,140,201,73,43,7,32,112,173,25,24,231,235,173,174,10,70,94,128,225,183,166,48,240,87,117,233,247,178,37,162,152,156,180,10,0,6,108,77,1,120,223,193,86,200,113,114,210,42,2,0,193,87,179,201,8,4,159,84,150,245,159,156,180,74,112,4,224,7,152,9,114,240,17,97,9,148,201,73,107,10,34,231,91,251,80,200,68,81,144,49,57,105,77,51,80,130,214,20,192,170,219,59,223,170,168,68,128,0,204,0,0,180,117,106,108,252,201,96,92,22,155,181,222,37,183,231,76,140,55,107,117,150,5,59,43,140,162,215,90,132,65,63,24,206,128,66,48,108,41,12,208,90,6,138,124,120,25,194,66,160,68,197,228,91,179,176,46,186,110,229,41,167,124,133,103,15,193,18,21,20,182,102,225,96,213,149,200,8,193,41,200,21,221,3,66,249,244,63,33,205,9,153,2,241,20,149,107,77,0,112,31,161,22,32,32,0,37,31,0,219,58,53,214,172,213,229,70,134,131,48,21,54,76,193,23,193,231,155,189,206,190,57,228,105,181,132,98,195,156,145,11,44,46,188,92,86,33,63,30,224,43,106,147,95,113,219,139,149,61,223,228,231,115,47,167,198,108,59,205,27,115,118,26,101,58,132,129,205,134,219,115,102,123,251,109,119,179,233,52,92,235,236,255,23,58,105,144,143,206,153,123,1,54,97,198,20,56,156,70,200,223,151,46,5,188,86,244,144,128,54,107,205,106,43,10,249,194,64,217,211,105,205,178,17,5,147,90,185,236,153,52,92,86,120,221,209,194,15,83,180,92,54,13,87,28,65,143,66,128,235,181,110,172,68,108,233,243,165,217,210,11,86,173,107,245,118,92,171,219,223,58,91,175,117,123,86,181,213,177,26,110,111,167,85,177,90,253,94,187,223,219,236,225,5,194,180,83,173,25,161,143,187,215,115,155,104,17,182,124,54,34,245,194,191,85,92,55,53,150,165,157,178,170,78,213,154,91,175,0,52,222,167,249,107,205,90,15,249,165,242,105,72,223,190,162,113,138,61,0,248,139,253,210,15,239,11,31,241,199,223,236,175,85,173,255,21,56,131,27,205,174,83,117,231,155,206,86,221,173,168,189,100,207,159,124,62,251,66,102,126,175,221,234,244,220,14,114,233,145,115,189,107,1,223,48,109,213,208,159,19,240,25,6,59,214,189,90,235,149,119,172,93,107,246,156,181,155,145,174,221,223,180,106,164,109,217,233,186,86,118,22,253,234,185,212,79,236,102,186,61,167,231,250,175,109,225,117,237,7,238,121,167,188,19,52,201,241,77,250,205,43,205,214,213,230,69,52,38,93,244,174,226,86,157,126,189,199,180,107,214,234,232,207,87,82,228,63,189,60,236,33,201,3,250,33,95,67,177,228,134,38,22,224,83,125,13,229,146,31,130,92,24,255,240,107,40,147,194,16,100,18,248,186,95,67,129,20,19,19,8,239,183,127,13,133,81,74,80,24,92,12,114,18,165,241,74,106,12,249,10,214,158,213,237,117,250,229,222,203,175,164,198,90,253,30,226,33,88,180,145,100,158,234,215,234,21,183,131,232,71,139,255,44,120,125,193,237,150,193,235,177,133,214,101,167,124,197,217,118,47,59,189,157,89,171,227,86,235,110,185,135,161,172,84,199,247,94,126,101,34,115,249,202,54,122,57,62,145,70,29,86,73,166,170,83,107,247,90,157,89,109,54,11,183,95,238,55,230,155,253,70,119,150,132,34,184,96,16,63,165,25,7,252,2,95,64,75,218,122,126,84,119,214,242,155,174,185,157,221,90,153,52,197,15,95,65,63,22,72,6,106,22,4,58,186,76,21,234,114,193,109,35,223,172,89,222,95,108,86,220,61,212,89,23,233,160,46,94,82,13,224,209,103,230,80,39,144,70,243,250,105,53,57,157,26,123,37,131,135,101,124,34,53,38,117,216,206,33,215,55,131,94,233,115,155,214,57,162,53,33,73,59,117,155,32,202,67,109,94,73,253,203,227,127,143,204,191,110,127,171,209,170,244,235,110,119,18,141,248,217,54,53,119,147,237,173,201,237,22,126,54,185,235,212,107,21,167,231,250,191,100,218,91,153,237,150,49,142,108,54,155,45,21,10,248,255,217,108,150,253,127,161,144,205,218,217,127,177,11,69,59,107,23,115,37,187,244,47,217,92,33,159,47,252,139,149,29,42,231,244,95,191,219,115,58,255,146,205,118,90,173,158,174,93,216,123,158,185,175,201,191,201,73,235,124,171,226,90,219,110,211,237,56,61,183,98,109,237,147,197,161,124,118,219,109,158,221,110,101,172,11,43,214,242,202,186,53,127,97,113,61,147,154,156,180,118,73,74,186,59,139,254,24,99,26,91,187,118,38,55,157,177,193,27,207,70,238,230,51,246,12,121,211,109,245,59,101,151,164,13,100,218,133,250,165,82,109,178,12,89,222,243,84,170,214,64,75,187,53,158,34,160,233,210,100,157,217,110,181,182,235,110,102,187,85,119,154,219,153,86,103,123,18,191,223,234,87,39,105,155,73,216,225,12,237,143,150,63,125,231,126,179,87,107,184,147,126,235,51,169,177,138,191,212,181,183,180,157,209,194,220,157,132,205,81,239,126,199,233,213,90,77,163,190,216,29,152,12,186,156,73,141,33,114,186,61,167,209,142,0,0,244,57,147,26,243,133,22,8,163,187,223,44,91,103,208,207,51,169,137,84,170,220,106,118,177,144,39,39,173,103,221,78,173,186,111,245,118,156,158,213,219,169,117,129,158,148,145,218,212,186,86,183,95,173,214,202,53,183,217,171,239,91,253,246,217,94,235,44,30,197,212,216,38,179,69,54,223,172,182,58,101,151,238,103,140,231,178,214,89,240,246,82,173,233,237,139,8,136,133,97,56,6,90,128,209,217,163,15,173,179,86,46,59,129,88,159,156,180,158,115,235,245,103,144,220,86,221,109,119,207,42,183,154,61,167,214,180,186,173,134,107,93,117,235,245,179,88,168,86,219,233,245,220,78,179,155,73,97,7,12,244,192,121,80,32,197,224,213,230,198,242,51,203,43,207,45,195,214,231,172,44,230,247,233,245,245,203,214,142,235,84,220,142,133,243,100,78,215,170,184,213,90,147,204,200,213,139,231,173,169,92,62,155,97,224,161,78,155,79,207,207,93,152,95,221,92,158,187,52,207,2,182,5,192,187,78,189,31,29,242,179,115,75,27,28,232,28,21,22,114,133,40,212,134,211,238,226,20,86,208,48,227,109,13,3,192,152,183,115,168,245,243,88,80,47,116,123,157,90,115,27,121,158,217,89,235,12,149,208,25,228,50,217,179,214,25,158,67,252,34,199,189,192,4,162,55,175,48,168,8,93,4,23,193,226,231,168,199,124,68,208,87,196,142,164,136,114,214,178,108,225,13,193,57,107,229,48,90,111,63,122,124,15,176,63,129,197,51,62,97,61,9,100,247,114,106,172,141,220,243,166,123,117,28,52,77,141,61,217,182,206,89,123,254,158,112,219,79,253,113,48,215,48,39,227,19,22,97,9,1,244,186,128,221,104,132,153,180,68,62,123,38,240,207,199,39,210,22,180,133,184,229,114,191,177,229,118,198,247,38,38,2,172,16,39,236,46,246,14,222,2,98,2,71,210,51,223,193,47,156,123,252,124,246,5,134,64,57,13,168,169,12,59,122,14,240,62,17,13,177,74,202,84,34,18,124,228,13,47,118,169,52,17,240,201,73,235,130,219,238,184,101,100,51,103,173,11,45,171,217,234,89,253,174,155,241,241,62,9,17,111,52,27,78,167,187,227,212,191,181,182,178,60,190,69,203,23,38,44,183,211,33,242,109,246,27,105,244,23,27,227,125,39,195,116,196,138,199,15,251,214,4,78,231,162,190,66,174,23,61,197,243,231,73,52,189,3,130,198,155,253,70,80,168,64,220,127,158,167,141,46,180,127,0,169,85,107,118,123,174,83,201,72,134,147,85,156,241,9,107,156,112,154,38,59,73,19,145,84,137,169,248,160,16,94,206,190,66,105,197,1,245,42,114,113,45,183,89,118,218,221,126,221,233,185,36,249,222,193,143,113,186,222,41,239,224,196,187,213,170,146,52,124,198,34,193,33,154,101,173,38,106,142,160,225,87,105,220,185,220,234,116,208,82,218,117,123,86,119,167,213,175,87,172,45,23,141,109,197,234,181,44,183,217,237,119,92,52,70,109,98,122,17,197,200,109,162,75,6,32,139,4,239,136,101,156,69,240,13,146,80,133,177,70,146,12,126,50,129,107,181,22,36,25,152,100,130,5,51,248,48,201,144,242,226,82,235,73,250,11,33,232,69,207,145,152,61,131,6,165,155,182,167,210,173,118,47,141,172,247,185,6,105,121,198,250,126,183,213,156,61,67,255,76,183,26,181,158,219,104,247,246,207,188,136,23,30,18,87,226,5,220,233,160,85,167,91,219,198,27,7,72,56,232,229,44,106,134,254,27,123,50,144,197,230,197,122,203,233,9,79,47,180,250,91,40,206,229,30,47,226,181,86,242,180,84,16,158,110,212,164,141,209,99,73,235,53,121,235,53,121,235,139,181,61,183,34,105,142,159,203,160,87,21,29,200,11,73,143,167,90,173,186,216,26,91,248,77,177,49,26,51,225,41,154,114,194,195,85,183,237,162,105,44,188,184,228,180,133,103,115,205,125,113,100,168,123,42,188,88,247,220,206,212,24,182,209,181,46,124,137,158,248,90,182,217,106,186,173,234,236,25,52,47,206,188,8,109,50,0,56,97,173,186,93,151,110,98,97,51,21,188,123,153,236,84,233,54,170,26,53,100,49,13,150,7,176,121,133,186,117,121,67,11,167,226,74,21,56,148,151,91,56,169,136,151,81,212,49,179,134,214,5,144,248,25,111,212,38,144,145,85,241,103,182,180,251,248,189,213,29,44,152,12,56,156,185,164,173,145,212,84,104,113,187,85,178,128,241,43,158,103,30,94,78,197,20,160,102,84,158,120,194,218,131,43,81,108,81,215,170,86,163,155,89,106,57,21,40,236,9,235,92,0,91,61,28,56,149,74,197,220,232,226,53,208,251,171,230,17,224,75,89,178,242,5,146,204,64,65,106,150,65,70,248,163,88,3,165,163,190,224,246,2,221,96,173,63,217,36,222,147,120,9,123,158,68,160,156,168,87,64,176,52,4,44,212,113,19,167,63,65,211,144,160,105,100,72,185,151,2,135,200,9,94,52,16,31,248,23,134,139,180,213,186,130,244,106,47,227,211,146,25,23,22,156,137,111,162,102,12,167,116,33,50,166,129,44,81,136,8,242,91,52,42,72,31,9,25,222,202,103,76,7,94,19,17,25,248,151,104,84,224,46,18,34,232,58,27,133,134,82,129,210,80,42,68,166,161,84,144,211,128,214,69,99,26,200,122,143,136,216,136,33,9,210,91,66,134,231,70,68,162,131,8,99,35,134,52,72,111,5,29,145,228,177,230,203,99,45,134,60,214,84,242,88,139,42,143,53,95,30,107,49,228,177,166,146,199,90,84,121,80,159,13,91,13,242,107,68,187,65,58,201,44,135,231,220,69,163,133,8,133,254,26,131,22,169,88,124,15,212,124,124,170,129,96,214,98,73,198,131,32,27,165,106,100,217,120,46,113,64,79,100,157,169,42,197,19,248,219,198,244,32,79,28,209,130,254,31,141,14,212,67,66,3,113,237,205,229,65,156,126,44,14,252,107,68,97,144,238,50,89,120,209,132,185,40,80,156,129,101,129,126,137,40,12,212,69,38,13,18,187,24,211,224,229,216,208,255,163,81,128,122,72,8,32,97,146,49,126,47,128,66,52,120,191,71,163,195,235,37,161,37,136,206,140,233,185,228,180,177,67,231,180,163,81,113,201,105,75,8,192,81,160,49,238,185,230,62,194,61,215,220,143,134,123,174,185,47,193,141,163,77,115,247,139,198,161,216,1,163,191,71,116,193,104,47,153,19,230,7,185,198,244,248,225,47,34,200,255,35,26,69,126,55,9,73,32,188,22,104,234,201,227,109,191,230,5,19,192,191,38,137,87,46,53,69,188,99,144,160,154,156,180,214,202,78,221,233,144,70,36,203,147,26,35,205,160,251,45,166,144,130,12,82,21,53,75,227,160,159,132,251,60,86,226,244,2,180,244,1,227,90,11,24,114,1,134,10,110,167,67,129,125,32,128,129,252,13,157,102,1,126,62,128,143,157,158,16,240,165,2,11,190,84,96,252,97,1,124,129,1,95,42,232,192,19,47,20,192,167,15,24,95,87,192,80,12,48,244,67,57,32,14,38,135,2,241,176,161,99,162,196,162,208,115,177,198,115,65,31,48,30,170,128,2,164,34,187,161,92,172,241,92,208,7,140,243,41,160,152,102,81,232,185,160,62,18,192,225,61,97,29,75,1,203,12,152,17,164,97,40,26,134,21,239,9,235,51,138,19,47,203,225,9,25,148,170,192,143,255,136,115,8,69,84,96,146,119,13,120,242,220,47,1,23,30,161,16,182,114,60,46,61,95,200,205,2,120,240,159,192,137,19,225,131,233,190,213,106,213,181,124,16,215,9,178,65,159,48,62,154,136,3,204,121,146,244,211,114,128,250,64,22,240,223,208,249,18,17,128,41,79,158,104,224,227,221,92,198,212,159,111,53,218,117,119,143,181,245,184,25,240,183,68,164,192,8,184,205,126,67,135,211,243,112,0,94,255,17,231,79,137,120,192,52,237,208,166,58,92,151,156,54,64,131,254,10,220,36,17,56,152,157,13,167,173,131,59,215,220,103,197,246,156,91,175,159,197,187,93,172,228,80,195,192,59,18,215,47,48,81,157,230,190,118,129,164,14,9,92,34,189,71,156,251,35,162,1,147,212,43,46,209,225,242,61,13,128,44,120,198,251,54,34,58,48,79,253,82,20,136,79,200,138,210,148,156,232,193,48,89,108,73,246,44,66,15,146,233,138,214,161,84,136,210,129,102,144,34,246,136,134,99,45,50,142,181,200,56,188,60,71,212,46,17,57,169,70,71,227,199,245,17,250,224,24,60,10,14,26,46,71,65,129,35,219,8,29,112,32,26,161,189,31,48,70,232,131,194,187,8,205,81,68,22,101,254,121,161,83,132,62,65,112,163,236,52,57,105,129,136,130,148,210,109,209,157,123,92,95,213,113,106,205,94,215,114,218,237,122,141,236,186,191,136,99,139,23,73,81,82,151,218,178,0,198,67,220,105,199,203,105,179,219,179,186,109,183,92,171,214,188,205,113,92,86,71,206,253,53,250,221,158,181,229,90,238,158,83,238,213,247,201,241,64,218,186,66,88,74,141,17,32,79,98,62,243,57,104,111,61,135,11,216,119,44,37,111,167,30,255,33,236,211,47,153,80,84,119,187,248,101,83,70,83,26,195,113,247,202,245,126,183,182,235,166,198,150,244,244,129,5,161,238,19,87,151,81,230,70,34,173,213,177,220,151,250,78,29,233,65,111,7,87,11,8,164,90,181,38,32,211,213,210,153,135,116,186,1,161,98,173,195,130,137,12,183,59,104,214,118,76,197,152,177,22,171,184,25,169,99,107,85,17,150,90,215,170,59,157,109,15,138,3,96,44,245,144,0,150,122,110,218,103,190,227,52,183,113,141,102,199,221,117,59,93,183,146,73,141,45,232,199,6,56,164,219,254,216,108,139,99,179,96,52,54,12,203,209,134,71,198,190,43,240,207,1,97,101,160,224,95,63,232,69,40,0,55,144,128,56,232,139,77,147,169,236,113,220,106,98,38,152,113,199,96,168,165,26,91,108,90,207,191,160,33,172,148,238,184,109,47,61,224,209,85,107,10,100,45,183,122,90,202,202,78,179,217,138,72,27,129,169,37,111,42,32,175,217,234,109,214,154,105,68,33,250,125,209,167,150,190,16,4,185,221,108,117,220,121,244,68,164,219,5,165,83,180,92,11,147,234,243,227,87,94,145,233,131,72,198,209,67,171,89,223,183,106,132,43,210,178,214,197,197,119,24,117,106,12,98,125,18,5,120,144,171,93,167,83,107,246,96,30,160,134,155,111,226,206,132,181,90,0,192,31,14,216,8,178,201,36,10,253,229,72,82,210,226,191,27,74,73,139,61,146,146,22,192,95,18,37,45,0,156,182,164,133,111,55,140,146,22,251,84,148,180,248,146,52,47,105,1,194,31,110,73,139,173,86,182,5,183,135,157,163,241,9,203,51,84,92,41,11,26,159,12,113,160,196,170,147,39,233,43,40,176,172,14,217,82,24,166,37,5,154,165,40,56,220,80,36,174,10,139,107,140,102,33,140,149,5,5,43,11,230,172,44,132,178,178,160,98,101,33,2,43,139,77,124,235,155,2,15,87,82,162,221,208,97,225,226,53,208,24,52,110,29,1,58,88,141,198,39,44,188,28,201,36,4,23,45,169,164,64,3,136,189,234,212,187,174,55,221,193,30,138,89,76,69,118,83,216,160,10,66,121,196,162,170,82,65,112,112,74,133,19,20,85,201,233,59,121,81,149,156,206,71,59,170,146,243,124,138,162,42,185,0,78,64,84,37,39,236,196,68,85,114,242,30,71,85,166,81,21,88,143,196,176,10,188,28,74,92,149,27,69,92,197,112,152,64,96,197,192,211,69,86,98,195,97,132,86,185,211,16,90,1,81,26,199,86,140,248,135,27,92,229,52,26,199,71,87,165,66,194,209,21,143,109,41,12,85,156,240,74,68,226,134,98,137,19,95,241,120,22,194,152,137,19,96,137,72,194,152,137,23,97,241,120,96,28,36,34,138,16,98,241,128,185,24,43,4,118,104,140,37,208,61,186,32,11,20,48,153,197,88,120,39,151,13,177,0,140,71,39,194,34,21,94,162,83,112,34,194,43,21,113,39,42,182,82,17,249,200,6,86,42,134,79,71,84,165,226,254,225,134,84,42,170,78,66,60,165,162,237,113,48,101,26,76,5,43,143,24,75,5,239,134,18,74,229,71,17,74,65,254,18,136,164,32,56,93,32,37,180,27,70,28,149,63,13,113,84,32,73,227,48,10,10,127,184,81,84,94,173,108,32,136,34,86,42,217,16,138,67,181,164,199,19,39,126,18,48,184,33,40,226,4,79,28,146,5,61,27,113,34,39,1,131,158,141,120,97,19,135,132,70,54,82,44,17,98,38,14,106,16,50,133,3,14,13,152,120,138,71,26,47,121,149,254,198,241,82,169,32,196,75,30,140,71,42,94,98,83,195,39,44,94,146,18,119,210,226,37,41,145,143,114,188,36,101,248,212,196,75,82,238,31,122,188,36,165,234,132,196,75,82,218,30,199,75,17,226,37,186,242,72,227,37,250,110,40,241,82,97,68,241,146,207,95,50,241,146,15,46,36,94,98,219,13,35,94,42,156,146,120,137,74,50,74,188,228,11,127,184,241,82,65,173,108,108,188,148,248,150,19,135,106,73,143,39,102,188,196,98,112,67,80,196,140,151,32,146,5,61,27,49,227,37,22,131,158,141,216,241,18,68,18,132,53,199,218,99,226,160,50,241,210,113,55,152,120,138,71,23,47,109,68,222,96,234,75,118,152,54,30,201,45,166,254,137,222,99,82,82,119,162,130,38,37,149,143,108,212,164,228,248,116,132,77,74,246,31,110,220,164,36,235,36,4,78,74,226,30,71,78,166,145,211,134,110,171,105,99,200,123,77,197,81,196,78,27,9,111,54,109,152,238,54,137,13,135,17,62,21,79,67,248,180,17,99,191,105,99,116,27,78,69,141,198,129,8,170,63,140,45,39,30,217,82,8,166,56,65,148,136,195,13,67,18,39,140,226,209,44,132,176,18,39,144,18,113,132,176,18,47,148,226,209,208,144,71,142,39,66,48,197,195,13,162,41,3,208,161,225,148,64,245,104,227,169,104,27,80,125,201,14,212,198,35,185,5,213,63,209,123,80,74,234,78,92,60,117,186,118,161,148,28,159,158,120,234,4,238,67,41,201,58,41,241,212,227,157,168,99,199,83,202,173,168,141,33,239,69,149,70,21,79,37,185,25,181,97,186,27,37,54,28,70,60,85,58,45,241,84,212,253,168,141,209,109,72,149,52,26,199,197,83,137,111,73,241,200,150,66,48,197,141,167,196,93,41,45,146,184,241,148,176,47,165,193,18,55,158,18,119,166,180,72,226,198,83,146,189,41,57,158,136,241,148,124,119,202,0,180,81,60,245,144,246,167,214,34,239,79,117,37,251,83,107,143,228,254,148,144,53,254,65,109,251,7,206,246,73,185,185,79,77,222,137,138,168,212,100,62,178,33,149,154,229,211,17,83,169,249,127,232,197,125,10,186,78,66,84,165,166,238,113,88,101,26,86,173,233,182,169,214,134,188,77,53,53,138,176,106,45,225,109,170,53,211,109,42,177,225,48,194,170,169,211,16,86,173,197,216,166,90,27,221,54,213,148,70,227,134,124,48,138,199,53,132,147,81,34,138,97,28,141,226,177,12,225,108,148,136,98,24,135,163,120,44,9,157,142,226,193,38,122,60,74,160,121,180,241,84,180,253,169,174,100,127,106,237,145,220,159,18,178,198,196,193,57,41,119,246,169,201,59,105,241,148,130,204,71,57,158,82,176,124,106,226,41,5,255,15,61,158,82,208,117,66,226,41,5,117,143,227,169,40,241,148,114,155,106,109,200,219,84,211,163,138,167,146,220,166,90,51,221,166,18,27,14,35,158,154,62,45,241,84,212,109,170,181,209,109,83,77,107,52,110,200,7,167,120,92,67,56,57,37,162,24,198,209,41,30,203,16,206,78,137,40,134,113,120,138,199,146,208,233,41,30,108,162,199,167,4,154,71,23,79,49,223,177,52,252,178,20,233,194,125,91,10,194,121,116,66,42,241,100,195,137,250,184,148,154,188,19,21,82,169,201,124,100,67,42,53,203,167,35,164,82,243,255,240,235,254,78,238,119,165,212,212,61,14,169,140,63,43,5,86,34,201,135,165,192,219,161,4,85,51,35,249,180,20,195,99,18,31,151,98,0,106,63,47,37,182,28,70,92,53,115,26,226,42,40,75,243,79,76,49,3,48,220,200,106,70,167,118,195,62,81,37,96,27,198,145,42,9,146,161,156,169,18,240,12,227,80,149,4,201,80,78,85,9,120,146,58,86,37,0,78,246,92,149,72,247,136,3,173,104,59,87,244,227,39,146,64,235,209,219,187,18,143,60,156,168,239,77,169,201,59,113,129,214,41,251,218,148,154,229,211,19,104,157,196,111,77,169,233,58,41,129,214,227,47,77,37,16,104,41,55,175,224,219,225,124,195,55,59,178,72,43,201,253,43,22,96,104,164,53,252,29,44,44,199,211,17,106,69,221,195,98,71,96,200,223,243,205,234,20,111,216,167,173,4,108,195,56,110,37,65,50,148,243,86,2,158,97,28,184,146,32,25,202,137,43,1,79,82,71,174,4,192,201,158,185,18,233,30,97,145,96,140,93,173,174,116,91,107,237,17,221,215,58,217,219,90,95,143,93,173,211,183,169,117,202,247,180,78,232,150,214,137,222,209,122,188,161,117,252,26,65,253,142,214,218,208,183,180,108,123,36,133,130,137,111,106,173,153,239,106,201,154,14,37,216,178,79,67,176,181,22,107,99,107,109,148,59,91,182,173,213,190,97,31,195,146,239,109,37,124,16,75,177,183,149,248,81,44,249,222,86,194,135,177,20,123,91,137,31,199,82,237,109,29,251,64,150,102,111,43,137,35,89,15,115,111,107,45,198,230,86,87,186,187,181,246,136,110,111,157,236,221,173,175,199,230,214,233,219,219,58,229,91,91,39,116,103,235,68,111,108,61,222,215,74,40,222,82,159,202,26,254,206,86,110,116,241,86,162,71,179,204,247,182,100,77,135,18,111,229,78,79,188,21,249,132,214,72,183,183,114,90,237,27,246,49,45,249,254,86,194,7,181,20,251,91,137,31,213,146,239,111,37,124,88,75,177,191,149,248,113,45,213,254,214,177,15,108,105,246,183,146,56,178,245,48,247,183,158,106,181,234,81,98,45,68,12,27,103,5,16,30,157,24,75,225,35,152,71,88,112,124,125,1,137,14,128,255,106,56,139,255,72,62,252,15,216,75,96,225,7,208,116,139,62,223,108,40,11,254,169,248,236,191,47,73,227,197,30,200,126,200,11,125,94,169,105,96,145,87,154,199,40,107,60,147,130,194,138,201,26,69,125,254,9,119,224,178,79,0,200,163,99,23,233,188,6,150,17,141,120,55,106,234,201,53,9,165,89,58,154,253,198,150,219,177,90,85,12,161,188,227,116,156,114,207,237,116,173,241,141,102,173,220,170,160,209,169,184,86,27,77,172,238,68,6,5,198,110,16,87,42,123,55,156,125,171,82,171,86,221,142,85,237,180,26,108,99,11,51,103,213,104,234,6,243,158,73,141,33,242,53,31,240,152,1,41,36,215,143,135,235,174,24,12,95,170,53,135,47,10,203,233,89,142,213,168,53,107,141,126,99,168,114,161,236,24,125,61,164,81,107,110,34,145,224,232,186,129,59,122,146,242,94,9,210,114,246,70,38,45,103,111,248,210,34,236,24,125,197,164,225,236,1,105,225,142,190,180,232,43,201,28,123,10,227,141,45,47,66,55,6,6,85,8,235,63,1,173,25,233,44,51,9,54,137,149,192,228,215,105,111,48,49,232,107,201,244,24,22,11,62,104,163,79,170,32,141,4,28,52,106,44,7,193,107,137,202,38,205,1,209,76,172,62,97,28,20,89,5,130,28,208,206,80,137,228,28,92,118,122,61,183,227,205,58,21,253,13,167,87,222,177,156,109,7,185,10,146,204,98,199,221,238,215,157,142,229,238,181,59,110,183,91,107,53,173,241,213,249,156,213,221,111,246,156,189,137,140,181,190,227,146,68,112,197,173,192,86,52,225,231,214,107,21,146,243,115,154,251,86,197,173,215,16,153,157,110,38,53,230,17,168,92,154,74,129,20,218,164,173,199,53,253,83,228,185,227,86,107,123,97,99,182,227,236,242,163,214,237,111,81,42,156,30,134,132,94,111,185,219,181,102,19,61,244,146,174,158,5,160,120,148,148,79,1,202,113,83,159,112,252,151,64,247,90,191,154,32,221,110,179,34,80,76,49,40,41,6,57,212,46,110,234,81,76,254,18,40,62,223,106,246,144,206,28,135,102,79,45,174,238,184,29,87,176,178,62,6,37,205,51,140,235,130,27,3,239,5,255,45,203,186,27,144,78,115,239,241,137,135,104,148,244,231,192,58,209,108,245,54,125,162,189,156,252,121,142,43,166,209,40,54,57,148,78,99,246,4,108,114,40,137,179,227,111,114,60,231,214,235,207,32,55,156,110,98,180,59,173,221,90,197,181,156,202,174,211,44,187,21,54,144,160,86,179,220,106,52,144,197,11,244,130,218,39,108,253,241,3,28,150,18,238,157,142,107,57,221,110,109,27,199,162,136,99,31,233,172,215,126,236,73,16,132,108,206,55,156,90,93,124,252,116,171,219,67,76,138,111,22,219,178,103,187,5,233,211,146,248,116,163,83,147,62,92,117,171,226,243,185,74,5,217,124,73,135,126,173,34,62,245,153,93,117,183,221,61,9,184,122,123,199,217,114,123,18,128,248,85,179,223,144,188,90,106,93,117,59,101,167,43,17,198,122,215,45,119,123,157,212,88,48,182,181,174,148,162,64,149,54,91,77,183,85,157,61,115,213,173,215,55,113,88,70,245,99,29,169,46,9,32,187,104,232,58,136,9,183,107,61,189,190,126,121,243,233,249,185,11,243,171,155,203,115,151,230,45,167,89,97,30,62,59,183,180,49,143,122,184,120,216,201,94,104,175,83,43,247,172,29,215,169,184,29,176,129,150,193,111,159,66,203,101,213,233,215,123,105,50,99,106,93,171,215,233,187,105,31,182,216,179,139,181,107,245,226,249,179,229,86,163,93,175,57,205,30,1,182,230,246,122,104,178,244,90,36,94,182,174,214,234,117,74,139,229,88,245,86,171,203,1,194,186,138,119,231,42,181,174,83,175,183,174,18,95,230,255,116,254,79,243,255,100,129,11,157,182,174,238,212,202,59,104,42,163,121,220,239,146,208,122,107,191,237,116,187,30,137,216,205,64,4,224,105,133,214,35,194,187,42,93,151,3,30,16,17,83,186,226,86,207,217,254,170,68,158,125,125,246,40,115,165,4,55,41,113,46,8,171,6,53,138,86,181,213,97,242,22,152,204,110,38,133,205,149,53,158,26,163,237,55,161,226,211,49,56,135,243,48,227,72,183,38,82,19,48,187,29,180,149,108,128,6,47,135,147,1,45,140,100,251,19,178,152,196,230,39,132,167,221,250,20,26,14,37,15,90,56,13,121,80,32,75,243,109,79,40,255,33,231,66,11,26,157,3,217,208,64,235,142,149,15,61,115,70,139,109,201,109,134,156,182,115,155,138,237,72,183,169,217,193,227,208,144,140,146,30,19,205,58,73,145,145,119,17,240,225,212,74,8,62,146,183,145,227,195,239,204,241,121,153,148,80,89,146,80,95,37,208,167,72,142,32,130,84,13,176,250,41,18,149,100,163,98,165,57,135,80,233,234,176,210,183,230,88,105,122,64,63,49,188,28,130,20,39,125,25,97,114,144,184,62,4,37,137,253,229,24,241,187,8,8,73,88,174,71,72,67,119,41,66,242,46,2,66,47,164,12,181,55,36,118,85,153,28,252,54,2,90,16,15,235,49,195,192,89,138,28,52,136,128,159,110,249,203,17,71,169,39,16,249,50,7,173,47,39,104,136,208,253,200,100,124,66,25,179,16,132,13,9,194,70,198,111,21,133,37,28,109,114,155,115,105,171,117,5,121,6,123,25,150,170,204,184,24,168,78,124,19,53,102,24,167,1,172,100,207,78,73,133,23,220,198,35,196,235,45,161,37,136,154,163,144,179,216,142,71,200,98,91,66,2,10,207,163,33,223,45,196,69,191,91,144,18,176,91,136,76,66,41,54,9,37,57,9,165,104,36,108,116,106,241,40,216,232,212,36,4,224,28,71,68,252,171,110,53,54,9,171,110,85,78,5,78,170,68,33,132,38,92,226,81,66,59,75,72,241,243,56,145,132,210,175,85,98,138,164,95,171,200,4,130,147,70,81,72,96,19,74,227,19,86,240,71,68,146,88,72,18,226,248,220,85,64,102,240,116,115,99,249,153,229,149,231,150,245,67,232,37,185,98,14,162,215,93,54,140,65,254,44,146,82,121,185,181,99,80,132,186,171,40,34,105,187,40,20,249,41,189,120,20,249,221,37,20,129,108,97,20,138,104,38,49,30,61,180,179,132,26,63,65,25,133,22,146,187,209,213,208,208,236,142,220,109,196,239,32,70,117,126,72,191,46,140,168,220,17,23,230,168,92,32,156,136,168,58,101,156,36,81,52,26,159,240,193,8,30,11,168,242,153,156,180,232,35,49,123,200,238,164,56,36,155,104,185,184,185,67,140,167,229,144,36,105,197,173,214,154,110,197,218,218,183,86,47,158,183,138,249,92,46,53,70,0,171,234,19,65,133,5,6,153,198,41,104,146,239,19,200,246,156,24,150,242,224,169,41,241,59,94,15,57,221,118,54,95,200,144,156,119,176,239,97,85,90,46,73,127,118,251,237,118,171,67,246,29,241,24,52,113,110,213,169,215,126,224,86,172,74,171,225,212,154,22,2,223,181,198,23,47,44,119,39,50,169,49,159,70,149,28,192,158,152,71,157,86,20,139,109,86,8,232,111,83,246,23,47,91,227,187,5,171,213,177,118,75,19,222,24,146,132,249,179,180,193,110,201,123,238,118,189,4,49,226,157,110,121,91,221,126,167,211,234,55,43,200,247,239,190,212,119,58,174,181,213,113,202,87,220,30,2,180,216,86,242,9,138,20,106,237,16,14,119,11,60,143,232,137,57,151,187,5,192,28,238,172,162,170,8,169,218,45,132,209,85,18,232,42,69,162,203,23,110,134,8,156,64,57,182,208,119,75,74,6,75,12,131,37,45,131,27,157,26,203,31,126,96,200,94,218,114,182,186,173,122,191,231,90,27,171,139,150,211,245,38,23,134,68,39,88,126,102,186,148,26,67,96,85,244,130,74,130,126,167,22,70,238,170,91,21,40,198,207,76,199,132,37,149,146,137,33,33,82,241,206,83,195,217,71,61,58,110,221,233,213,118,93,52,123,60,78,51,152,23,132,80,197,206,52,195,206,102,199,173,146,13,144,62,238,166,101,143,250,167,44,127,254,195,48,6,221,90,111,199,237,68,49,124,214,56,217,215,226,205,157,210,212,97,64,196,220,181,58,22,54,120,105,244,91,173,231,237,141,73,237,78,38,53,230,113,161,218,59,2,53,154,116,94,232,21,161,95,171,112,106,128,159,24,43,193,198,226,5,86,11,48,16,36,152,130,141,86,50,12,78,69,44,88,200,250,253,90,69,75,41,235,80,179,52,243,239,124,234,29,111,195,253,170,91,175,91,120,119,214,219,112,247,73,118,80,51,188,57,155,1,27,191,4,18,248,85,66,62,176,203,193,238,239,38,6,69,84,245,42,3,45,237,54,251,141,115,189,78,187,156,241,246,2,50,224,173,86,161,61,79,157,83,233,224,177,106,192,144,58,225,77,73,90,12,98,57,94,159,140,229,102,182,51,150,51,151,26,11,224,168,70,10,216,22,31,64,56,197,200,147,151,80,76,30,171,40,166,70,220,163,119,171,213,219,241,137,30,239,78,96,195,66,42,231,198,187,19,62,19,54,229,2,195,86,113,49,205,113,129,26,107,185,240,189,127,150,11,240,216,88,238,117,191,15,96,198,35,223,73,141,5,48,85,212,195,146,99,175,177,150,122,26,45,176,180,247,188,135,198,148,119,221,114,191,227,86,104,42,182,155,26,243,224,42,8,205,131,178,80,138,13,146,41,238,170,209,100,160,202,105,103,246,67,229,185,187,232,93,23,219,177,58,237,22,226,117,43,197,232,182,209,169,197,235,181,234,86,99,116,244,210,61,49,80,246,107,149,24,221,184,28,74,12,138,253,220,70,204,190,56,11,17,189,111,144,47,136,222,215,139,237,67,122,226,162,158,158,219,141,112,62,5,87,180,113,135,246,2,16,143,204,233,20,178,229,254,80,15,167,120,229,218,33,71,68,242,35,59,34,162,171,128,63,201,135,53,116,117,239,195,60,54,241,245,175,119,47,140,174,222,157,28,108,33,46,2,9,72,195,106,221,85,83,180,56,170,82,119,129,100,77,153,187,138,216,210,232,170,220,193,44,8,173,112,87,145,59,21,163,192,125,24,101,224,42,250,166,79,64,21,184,138,182,153,135,83,4,142,144,39,84,2,30,44,244,126,65,55,243,200,171,231,102,31,150,216,66,103,240,50,74,157,243,201,45,164,101,18,167,137,221,246,19,136,73,114,210,223,127,55,156,66,215,226,72,142,250,3,6,147,56,235,15,192,105,15,251,243,237,134,82,229,90,60,13,85,174,129,40,205,143,251,3,233,15,185,198,181,168,86,55,80,226,74,141,181,174,72,74,168,103,229,235,149,56,208,67,170,103,229,176,12,187,156,149,71,55,228,106,86,14,221,40,74,45,121,148,94,165,165,129,74,136,85,149,33,58,225,87,85,26,0,23,43,40,67,128,131,58,70,51,117,22,106,21,67,16,208,130,66,3,224,250,90,69,14,108,80,170,104,0,57,180,84,145,3,206,86,42,74,157,142,99,23,42,242,98,138,80,146,199,184,72,49,42,242,4,212,81,10,242,56,167,45,86,61,158,72,64,132,114,60,206,65,140,85,141,199,19,48,218,186,15,169,66,113,101,31,178,54,160,234,131,17,66,194,37,3,22,221,252,195,211,170,218,234,52,156,158,118,239,63,171,221,251,231,244,37,169,173,127,20,126,250,209,73,64,164,166,24,192,14,41,6,224,244,42,169,90,0,21,161,234,77,253,156,122,83,95,240,132,232,38,129,92,91,96,130,151,159,182,49,58,149,66,58,77,78,90,243,205,126,195,60,31,236,54,251,13,38,25,28,116,127,100,114,193,226,7,86,34,95,225,54,70,14,72,214,154,110,101,5,133,156,225,116,225,200,20,228,28,96,173,6,56,98,137,123,162,65,72,91,85,167,86,199,233,178,38,206,244,245,155,222,214,51,110,158,193,39,46,125,2,148,167,66,3,150,104,247,77,68,9,137,101,43,1,0,143,85,166,209,67,249,170,140,159,170,125,248,153,31,21,109,133,120,153,31,184,218,249,211,74,204,6,248,175,134,147,12,40,141,34,25,0,216,75,32,23,0,160,233,82,1,124,179,161,100,2,74,167,33,19,224,75,210,56,17,0,100,63,228,60,64,73,169,105,67,254,152,10,139,9,24,95,157,127,10,109,180,20,41,104,160,247,143,89,244,9,125,45,132,5,154,196,151,66,38,39,45,170,96,17,156,142,198,150,91,169,184,21,171,65,167,38,49,196,25,252,61,251,86,199,123,124,22,59,36,228,226,129,52,204,16,215,186,86,219,237,32,71,206,173,88,29,183,220,239,116,107,187,110,125,63,67,92,24,134,158,135,235,197,172,93,169,73,67,1,179,116,55,89,200,216,148,119,106,12,195,52,184,149,182,123,165,214,246,119,163,174,160,176,128,91,74,87,221,151,250,53,92,178,19,186,200,119,221,94,106,204,111,111,224,124,116,104,91,143,0,239,111,229,2,9,7,77,92,35,225,219,225,44,147,83,163,88,38,89,38,19,88,41,89,128,186,197,82,210,114,40,235,229,212,105,88,47,161,48,141,151,76,118,4,134,188,106,78,233,20,111,193,237,33,35,162,61,235,131,140,140,252,164,207,149,90,72,110,75,64,230,25,14,29,66,223,184,72,145,122,111,85,215,244,174,186,109,23,13,79,132,66,168,14,237,194,214,66,177,128,30,238,226,113,169,214,92,236,185,178,34,216,208,90,1,246,118,210,26,134,34,212,252,16,224,154,210,36,182,234,7,67,241,235,126,112,103,88,249,67,94,75,106,127,146,231,1,212,255,132,241,144,99,43,128,32,15,180,51,172,2,146,243,176,209,172,189,212,23,138,120,157,122,221,114,235,110,195,69,138,133,11,49,132,85,179,143,59,146,243,78,228,154,216,86,147,30,121,170,117,73,134,0,107,100,217,219,180,239,150,157,186,211,193,181,203,56,49,211,195,59,252,227,212,31,34,119,113,53,91,228,124,20,61,60,224,86,38,50,169,49,74,162,106,97,6,117,80,132,38,143,105,242,151,24,248,11,67,230,6,180,227,107,202,182,92,198,161,115,202,59,120,132,188,138,20,44,135,12,245,50,200,140,242,157,61,226,208,145,251,194,186,61,124,107,216,158,91,238,247,24,175,200,43,130,240,33,99,88,253,38,254,214,23,242,102,144,4,3,93,217,113,59,110,38,53,70,181,1,79,34,50,131,117,37,81,53,56,252,242,161,63,185,85,11,197,97,20,45,48,214,79,244,194,152,215,195,113,195,166,71,225,134,113,108,38,224,135,113,16,117,142,152,172,233,80,60,177,233,211,224,137,49,210,52,118,197,184,49,24,178,47,54,173,213,62,82,11,128,45,87,104,53,0,177,111,170,122,0,252,86,157,207,144,224,165,75,96,104,89,128,14,47,125,27,5,47,89,173,116,222,32,93,207,164,24,201,59,189,11,42,226,244,24,133,139,131,54,143,194,51,197,167,82,36,40,70,247,165,158,75,78,59,130,171,219,112,218,172,151,235,119,127,232,14,238,101,167,214,57,190,115,248,204,179,18,247,150,128,54,118,111,219,168,185,239,222,226,206,208,189,37,175,37,238,109,210,28,0,231,54,140,3,206,185,133,28,208,206,208,185,149,115,176,220,90,107,59,29,230,140,26,221,158,98,125,218,96,95,165,223,236,186,61,122,136,191,133,211,152,147,147,240,6,219,134,211,254,223,200,189,235,237,176,249,61,226,205,226,171,172,41,74,3,119,181,217,218,236,226,198,222,150,11,233,26,236,186,120,175,121,190,158,113,247,37,30,108,87,239,194,94,113,247,121,15,22,195,49,245,40,175,184,251,190,200,209,239,2,85,207,18,209,70,160,139,249,8,170,71,36,189,32,1,16,234,165,36,188,193,3,222,181,167,123,53,246,58,94,144,81,52,240,172,41,225,90,65,0,151,148,80,225,137,130,252,245,53,114,174,147,188,90,55,72,139,80,163,43,201,110,210,55,195,113,169,103,70,146,217,244,153,75,34,171,233,3,211,102,52,217,86,67,241,161,103,78,131,15,237,9,210,60,147,233,75,126,200,158,243,140,74,201,136,211,140,151,184,80,167,153,172,162,42,167,25,191,85,59,175,44,74,186,170,134,250,203,58,148,244,173,33,74,111,173,212,57,148,254,122,170,184,222,146,188,13,201,217,66,164,104,205,139,224,42,163,230,58,79,153,129,77,22,146,8,208,159,165,69,26,134,240,71,232,132,207,53,247,57,39,92,230,128,251,31,116,175,239,123,223,62,159,156,180,94,220,110,181,182,235,110,198,91,122,50,115,205,253,23,241,253,19,103,201,253,19,200,89,34,206,186,143,230,225,58,235,137,239,22,218,17,119,11,195,42,146,254,119,215,122,17,9,108,179,223,169,191,168,43,79,34,233,83,182,86,12,95,243,163,251,6,72,46,153,250,36,9,145,124,185,146,211,220,247,162,2,73,81,27,113,160,245,223,43,201,31,191,94,201,83,58,209,89,241,222,12,197,89,201,101,71,225,172,4,204,37,224,172,4,192,116,206,10,215,106,24,206,10,150,221,35,239,172,120,130,52,118,86,2,201,15,215,89,201,101,85,74,54,252,29,80,57,210,164,174,168,102,128,38,114,63,53,26,215,126,7,199,118,134,105,44,195,85,212,131,170,88,74,89,164,143,215,211,68,171,172,43,84,184,237,45,127,24,100,203,104,164,251,55,76,104,195,137,139,222,142,211,148,81,151,38,217,1,79,123,82,99,75,166,148,194,123,57,124,50,235,195,163,17,95,1,225,209,232,26,18,89,128,68,186,1,149,98,62,108,193,132,204,237,142,235,244,220,142,185,52,23,76,165,9,114,67,219,190,52,183,69,105,46,244,36,183,101,197,164,19,72,116,193,88,162,37,72,168,27,80,42,217,36,31,66,117,188,25,141,83,39,160,86,222,140,210,233,227,123,162,140,205,22,221,81,230,245,112,124,82,123,20,62,41,199,102,2,142,41,7,81,231,157,202,154,14,197,69,181,79,131,139,202,72,211,216,79,229,198,96,200,206,170,173,213,190,17,122,172,34,102,175,166,95,106,97,142,117,208,95,196,181,20,11,209,82,100,44,110,60,52,110,52,60,11,177,184,89,136,200,205,66,60,110,22,162,114,67,195,140,200,136,244,193,140,136,39,136,104,34,163,210,196,55,235,181,134,219,237,57,13,211,125,122,195,0,199,7,171,136,112,56,180,143,67,156,68,67,156,158,39,221,246,86,48,18,39,52,200,49,164,213,60,204,49,113,204,99,196,57,134,116,158,132,72,199,144,212,147,16,235,24,146,106,30,237,44,245,150,91,87,165,228,202,199,190,220,239,116,220,102,207,66,132,100,72,111,82,2,237,221,27,236,125,217,23,23,138,160,30,207,213,122,59,53,178,215,159,65,186,129,240,169,12,193,20,212,134,205,102,235,42,137,43,234,168,83,160,27,248,133,40,245,48,70,4,137,179,188,44,68,230,101,65,203,203,52,28,131,128,151,109,200,203,182,156,23,138,38,92,137,174,146,134,248,141,183,200,193,221,16,150,67,254,251,28,240,67,204,78,29,135,136,157,128,87,50,82,78,179,2,196,235,125,148,153,18,104,22,44,130,155,171,9,189,30,247,228,47,101,132,200,174,121,98,136,200,190,31,78,140,152,27,69,140,200,51,154,64,144,200,131,212,69,137,210,182,67,9,19,115,167,33,76,100,197,105,28,39,242,163,48,228,64,49,167,87,193,17,70,138,18,212,126,168,40,95,238,142,21,44,74,208,45,197,196,165,143,23,165,136,220,184,152,180,65,150,4,213,66,76,158,244,81,163,20,81,76,158,66,2,71,169,248,150,91,87,117,234,72,150,44,249,29,126,100,117,143,168,136,11,97,24,23,212,24,23,98,97,36,43,107,156,64,156,244,148,136,116,215,233,24,152,9,119,175,71,46,158,61,103,61,255,66,96,88,231,247,122,110,179,91,107,53,145,129,124,57,53,134,80,226,103,21,183,130,218,207,90,214,248,147,21,223,86,181,183,124,19,217,198,245,168,19,227,205,90,125,34,237,245,66,144,72,183,113,236,55,5,175,113,128,57,235,71,178,118,118,202,70,143,151,157,134,27,60,181,206,176,31,80,169,212,186,120,233,56,131,154,174,59,219,160,165,21,92,162,53,5,226,75,166,199,197,90,221,109,6,8,48,240,73,15,184,255,11,137,210,81,135,87,210,35,21,64,46,92,0,164,66,53,140,255,28,95,247,58,76,246,87,154,110,171,58,146,209,247,115,5,198,163,207,244,24,14,251,152,147,112,246,131,42,185,227,10,1,193,144,74,128,126,25,129,21,128,223,58,6,247,244,34,50,143,21,239,196,103,175,101,105,244,63,131,237,207,56,185,106,139,78,62,171,217,175,215,233,55,154,154,251,98,69,184,127,131,22,61,104,144,166,23,233,35,103,216,105,146,50,121,238,216,169,211,237,182,202,53,92,41,142,35,152,90,143,4,77,149,150,255,57,174,0,77,198,191,107,187,213,38,95,231,34,22,222,51,14,214,57,44,252,111,166,198,230,55,47,4,207,12,124,93,207,138,62,159,125,1,212,194,227,250,251,174,181,237,54,221,32,70,3,92,55,220,222,78,171,34,242,173,162,147,78,98,66,102,14,147,185,232,63,138,66,165,253,66,106,194,108,80,225,172,134,67,234,123,128,110,179,219,239,120,161,170,151,116,67,49,101,80,176,79,152,192,39,80,28,11,95,189,135,207,36,184,189,111,122,91,145,158,64,170,78,173,222,181,106,85,171,217,242,8,162,199,34,72,55,167,131,83,139,42,249,120,211,28,142,227,106,240,44,138,132,114,198,18,130,19,159,145,16,201,216,226,88,126,159,59,1,225,29,12,9,174,189,105,193,211,57,25,235,169,125,171,66,62,184,74,242,65,205,150,242,194,28,239,104,181,3,78,105,179,178,97,13,7,168,211,37,179,14,10,139,62,136,34,169,60,150,20,226,251,98,88,39,54,166,68,205,131,104,199,212,95,161,97,13,118,87,144,165,123,57,53,150,221,203,58,105,43,187,103,151,209,207,169,2,254,153,195,63,179,232,103,41,143,126,230,170,248,73,9,63,177,241,79,220,190,52,131,127,22,130,231,4,66,169,72,123,33,4,145,187,185,1,122,66,74,169,10,218,224,223,109,252,60,91,33,8,84,84,187,113,168,182,177,60,114,4,206,20,70,64,112,210,159,83,0,80,17,8,71,75,111,137,16,135,219,151,74,65,175,82,129,32,192,47,166,242,1,237,20,208,12,0,13,192,145,183,70,130,114,48,2,219,5,180,39,205,13,66,224,179,227,191,160,157,161,124,103,0,8,55,42,7,213,145,112,192,80,90,9,128,146,177,153,2,58,67,222,18,52,161,124,96,4,248,197,22,30,253,44,70,64,166,30,249,89,40,1,196,69,192,19,6,81,132,244,150,121,178,236,28,70,144,47,2,160,83,10,14,242,128,131,41,160,245,211,248,167,29,232,126,150,252,142,159,103,183,8,2,76,133,189,5,88,78,110,234,97,17,225,110,5,99,170,245,98,33,111,125,73,240,19,77,41,10,220,45,111,3,97,130,121,75,209,84,121,14,236,105,140,32,171,150,160,229,11,112,38,166,0,49,7,6,182,179,160,165,84,35,52,132,160,64,232,205,2,9,154,176,79,132,86,0,66,43,1,66,171,20,37,230,32,199,99,38,202,151,205,25,136,206,9,17,93,160,69,241,150,157,2,75,175,37,144,139,16,232,213,78,34,64,153,40,68,208,96,38,139,202,71,104,7,140,231,243,64,44,4,101,222,72,247,128,136,18,93,56,169,0,9,2,21,165,145,69,39,227,30,139,8,178,175,154,177,162,208,74,129,154,82,161,21,36,66,195,51,57,137,25,171,18,90,96,139,124,169,105,40,141,33,52,96,42,84,236,43,102,236,148,153,190,97,17,21,13,20,46,108,198,30,215,216,21,139,10,1,134,105,29,118,29,181,51,214,72,20,106,49,26,140,193,116,208,33,134,24,49,7,9,205,91,169,24,241,68,59,142,34,234,197,72,28,175,16,117,204,27,169,163,191,208,135,205,228,184,234,104,58,147,139,249,152,234,168,18,35,230,192,92,20,81,197,200,140,1,193,60,29,83,29,85,98,196,34,138,170,142,42,49,202,180,17,35,48,87,71,181,40,120,227,56,69,197,136,199,128,184,136,192,77,159,154,14,80,150,84,74,57,99,32,204,173,97,175,201,37,96,139,244,84,71,158,225,158,84,76,17,112,146,181,12,5,43,81,83,199,72,178,195,85,211,66,24,213,80,89,177,185,142,46,89,67,4,158,235,8,98,74,50,147,169,190,71,85,220,45,137,120,5,107,90,142,32,223,99,88,83,99,218,67,213,23,115,0,165,28,79,68,68,137,101,162,198,28,152,15,26,145,117,217,64,149,61,81,39,159,241,226,68,173,157,201,199,113,6,98,138,8,228,186,168,172,9,237,32,207,66,127,150,211,192,55,173,24,200,116,58,166,250,26,7,226,10,26,163,171,169,158,101,237,162,15,57,243,87,61,204,193,20,80,65,215,64,92,163,89,244,165,244,90,30,185,199,90,244,245,160,185,48,50,136,112,104,182,112,134,167,154,102,223,8,202,170,129,0,217,48,18,207,228,100,23,122,150,80,62,227,21,51,248,86,115,143,19,179,170,249,89,12,228,75,81,86,2,113,217,89,3,113,77,15,219,47,42,194,92,5,160,49,178,160,212,28,7,34,146,44,23,57,0,58,11,64,8,244,150,192,106,97,179,121,50,44,34,245,114,113,124,209,5,11,14,51,87,35,210,30,61,235,24,79,68,68,56,91,64,212,116,193,169,128,110,89,32,77,147,164,217,84,136,48,143,157,117,20,136,227,196,197,207,100,137,184,242,129,250,50,92,202,4,18,144,72,136,38,57,59,42,16,89,66,44,170,64,68,237,2,230,218,68,32,44,117,177,150,76,25,155,26,223,45,116,239,10,236,4,186,64,127,76,114,96,102,147,49,254,102,105,33,140,118,203,223,133,42,185,70,210,148,78,198,232,34,34,178,174,0,89,207,8,116,25,239,178,209,245,192,54,73,151,85,34,43,168,21,45,235,24,139,131,232,65,96,116,113,5,73,193,2,240,127,224,202,76,5,2,246,150,41,103,184,253,22,16,172,100,131,178,12,7,217,108,87,201,87,4,27,122,168,197,96,36,160,202,208,245,96,10,134,71,170,61,53,16,242,105,192,89,236,30,85,150,76,52,74,5,216,129,97,80,230,12,80,138,125,9,151,89,136,32,207,55,98,182,188,84,139,15,68,35,131,16,120,21,89,232,120,17,138,166,4,110,84,38,93,228,198,235,27,32,32,158,26,195,205,148,130,27,149,41,20,185,153,18,188,10,37,55,192,77,151,164,203,243,74,110,248,236,59,229,166,152,230,130,36,26,1,128,253,250,98,85,129,120,138,65,12,28,47,81,17,5,160,5,129,148,28,156,98,208,212,79,209,150,193,68,131,94,16,165,14,120,171,176,62,132,174,113,250,68,238,116,26,164,150,183,36,152,45,25,226,130,22,37,53,30,118,26,26,143,0,65,232,190,106,60,19,130,69,164,159,244,122,19,98,11,35,199,66,11,54,137,56,27,194,171,169,185,9,177,69,53,149,217,16,126,210,69,53,33,54,28,100,21,136,227,155,16,27,236,136,75,58,39,97,66,130,186,10,206,134,152,114,19,102,66,192,76,102,7,135,239,28,215,132,4,222,53,103,67,116,138,24,197,132,96,17,201,108,136,116,38,199,48,33,160,182,133,181,33,86,66,38,4,84,72,169,28,144,99,236,169,209,228,184,161,3,98,106,60,138,105,97,203,221,204,1,137,103,60,130,132,84,168,3,18,207,120,128,121,0,209,36,103,60,4,45,18,185,57,158,241,192,28,232,7,234,120,198,35,216,141,149,204,97,145,155,232,198,3,91,83,51,7,68,165,136,122,227,1,114,118,97,14,72,60,227,1,140,93,152,3,18,207,120,4,17,142,196,1,49,55,30,234,173,12,62,219,18,41,122,49,49,30,193,154,28,35,122,49,49,30,138,121,144,23,20,52,174,241,8,56,8,65,19,215,120,0,45,82,185,30,34,55,81,140,71,48,200,33,209,139,200,141,153,241,16,2,16,125,244,34,114,19,102,60,130,116,78,140,232,69,142,152,53,30,65,140,22,35,122,49,49,30,242,153,156,160,241,8,6,57,70,244,226,35,208,148,152,5,101,209,9,38,64,224,124,214,22,21,87,132,161,139,110,66,132,0,68,31,189,84,4,53,13,51,33,60,2,163,232,5,162,9,51,33,66,58,199,60,122,17,185,145,153,16,33,157,19,53,1,34,114,195,66,208,166,115,204,77,136,200,141,184,232,39,152,0,129,136,65,16,152,92,2,68,62,147,19,76,128,64,19,18,236,136,39,152,0,129,38,4,111,115,29,163,206,55,212,132,128,189,76,243,24,6,32,14,53,33,90,53,53,55,33,5,65,77,203,2,130,4,18,32,16,141,7,193,56,235,104,110,66,88,110,2,45,74,48,1,2,209,128,116,78,114,9,16,136,70,72,231,36,157,67,5,190,105,94,171,136,113,77,72,248,76,62,166,9,193,99,144,116,2,4,154,144,96,209,103,108,136,170,38,54,74,26,132,152,16,176,162,29,59,13,98,203,114,168,252,78,96,178,57,84,91,146,117,76,58,135,138,109,145,152,117,76,46,135,26,100,91,108,49,235,152,132,9,225,179,45,18,110,142,103,66,228,51,89,194,77,92,19,162,8,161,20,110,136,68,17,195,76,8,230,96,56,105,16,224,190,15,39,13,66,80,130,114,80,19,55,68,101,66,30,114,50,196,206,9,67,55,236,100,8,131,114,120,201,16,6,205,240,146,33,18,110,134,145,12,145,112,51,140,100,136,132,155,209,36,67,36,122,120,106,147,33,185,52,111,66,48,103,154,98,252,212,88,44,103,196,220,144,128,121,160,138,103,166,132,1,140,98,72,240,76,142,26,207,76,9,202,170,54,36,218,221,88,125,60,3,209,168,13,9,70,112,156,120,70,228,134,53,36,120,12,142,31,207,136,220,72,108,209,241,227,25,145,27,120,62,121,72,41,145,212,152,84,17,147,75,137,4,149,227,67,74,137,0,115,125,252,120,70,102,72,112,50,36,202,225,169,168,134,228,216,149,33,37,97,252,134,94,25,82,74,143,164,50,196,67,51,228,202,144,210,136,42,67,160,212,134,88,25,194,14,206,113,162,26,43,90,101,136,168,136,167,182,50,36,159,230,45,9,73,121,147,168,38,238,41,193,209,108,247,86,133,97,28,250,118,111,85,80,217,161,108,247,66,52,67,220,238,21,185,25,202,118,175,200,205,80,182,123,69,110,70,180,221,43,234,225,169,141,112,162,155,19,140,32,233,125,27,43,70,237,59,209,244,145,214,190,51,40,213,230,228,184,181,239,12,26,25,132,100,106,223,37,220,12,163,246,93,194,205,48,106,223,57,110,70,88,251,46,81,196,36,226,156,175,97,237,59,195,19,113,91,226,157,255,54,52,24,66,0,162,143,103,166,133,113,210,26,140,28,17,81,165,24,104,139,152,72,166,66,16,148,149,59,170,173,226,114,8,37,185,51,233,56,37,185,42,47,8,158,232,149,30,23,5,241,129,108,187,153,7,65,144,137,119,159,84,120,1,22,61,101,9,86,52,102,54,170,34,72,72,68,73,14,186,192,146,5,140,157,138,46,114,202,107,154,161,75,42,28,229,62,154,146,46,0,186,160,18,23,60,186,58,35,65,15,42,102,137,194,105,207,233,43,143,183,66,18,167,25,52,129,227,85,208,35,80,209,171,26,94,15,26,191,30,48,247,10,152,211,43,14,117,8,2,61,189,226,176,171,185,7,238,123,88,1,3,79,47,84,129,16,4,57,32,22,160,166,244,12,163,29,116,99,58,231,4,53,149,29,32,197,106,10,173,71,84,208,132,56,104,40,75,1,4,198,55,21,239,62,209,92,96,198,27,53,22,168,5,96,166,184,123,91,148,20,17,243,7,73,81,17,196,46,162,192,216,137,20,153,0,37,4,137,39,175,37,5,76,133,64,238,204,77,93,112,102,204,24,136,43,38,2,149,147,162,242,151,226,113,96,155,12,248,22,131,24,196,104,226,186,102,192,147,217,1,7,39,45,143,29,33,93,113,115,96,41,221,1,135,45,3,196,97,78,38,48,21,80,247,139,96,178,84,4,65,149,1,17,170,219,152,136,141,146,220,52,96,2,154,16,84,22,116,127,26,240,1,183,185,40,131,54,0,10,195,13,213,237,70,30,141,150,244,252,254,52,212,34,224,5,41,145,137,222,17,24,118,120,141,6,119,127,16,48,21,42,138,68,64,162,219,91,224,219,76,121,81,55,88,112,84,23,239,168,16,171,129,90,255,63,123,239,218,219,72,146,29,136,206,87,241,87,196,104,6,119,164,54,197,183,168,42,214,45,95,171,37,86,181,110,171,164,130,30,213,51,211,110,176,130,153,65,50,172,100,70,118,70,164,36,182,70,128,125,109,220,7,46,176,246,2,222,253,48,11,120,109,24,11,120,63,120,103,247,195,46,188,88,47,252,103,60,51,189,159,246,47,44,226,149,25,249,34,147,18,69,149,52,204,193,84,139,153,17,231,156,56,113,206,137,19,231,196,35,123,133,84,94,133,118,212,252,220,227,108,242,137,48,204,117,26,104,35,250,215,244,74,99,71,47,24,179,157,204,115,187,163,165,39,121,167,133,100,128,147,136,95,150,147,67,108,170,228,118,58,11,213,54,25,146,231,161,230,17,212,206,64,19,229,15,98,8,210,195,200,142,33,190,173,232,223,216,225,49,205,114,210,250,230,110,23,203,163,113,94,52,25,51,156,150,209,204,237,136,155,177,243,125,242,206,183,200,34,43,242,174,115,129,10,234,90,134,89,150,194,186,99,28,121,174,92,93,171,28,141,104,122,216,49,38,226,198,12,121,59,53,67,54,79,80,55,125,136,122,222,68,92,192,105,42,22,201,161,220,24,197,22,120,208,147,152,136,199,71,209,100,107,166,182,35,67,16,80,140,129,81,162,78,254,123,31,100,74,184,205,81,90,37,172,141,38,43,182,188,48,88,97,138,96,43,37,233,89,103,57,78,29,209,94,38,185,60,7,202,59,182,0,25,226,107,167,90,48,247,152,92,164,5,121,40,115,91,96,165,186,212,52,88,77,67,4,155,229,196,136,93,159,53,98,231,180,224,110,40,179,76,164,177,82,208,40,218,54,12,150,169,122,138,106,52,131,234,148,45,218,73,202,195,12,52,105,191,40,255,188,190,40,156,99,198,130,234,121,243,0,241,111,211,180,187,166,105,49,156,182,112,8,74,250,69,177,200,86,42,106,116,135,156,136,225,252,22,8,98,154,87,209,20,204,137,164,146,68,133,131,152,234,180,32,179,39,96,82,234,116,64,42,107,160,200,52,118,50,50,138,12,143,47,182,41,55,107,190,31,245,193,99,236,168,51,194,179,197,211,42,185,27,222,50,66,100,121,102,96,158,240,161,225,155,206,138,31,102,19,49,43,124,24,173,171,152,25,63,156,29,214,204,10,31,230,132,53,243,50,204,243,135,15,23,26,47,202,10,193,125,10,241,162,188,80,155,149,100,215,178,226,69,113,207,213,152,4,166,41,122,132,120,81,94,180,197,36,238,62,241,162,66,9,60,211,29,110,230,177,232,174,177,149,169,235,139,94,150,179,99,43,105,147,87,32,129,23,95,208,154,23,20,152,58,126,21,140,9,100,79,161,114,231,239,233,56,82,241,41,212,204,160,192,108,34,140,41,112,24,71,202,94,33,53,71,100,194,152,246,62,252,134,183,44,143,175,244,64,27,222,66,159,195,24,209,178,156,14,48,191,207,209,142,167,53,196,36,208,144,238,226,167,253,62,76,54,214,244,59,139,249,25,165,236,173,74,198,240,98,90,80,197,156,237,168,204,246,32,137,64,205,139,116,231,71,154,92,200,227,44,140,184,101,178,40,134,179,184,213,52,29,131,102,14,27,31,100,217,67,171,156,99,174,211,29,56,213,106,74,161,108,162,100,255,37,238,186,139,164,104,222,203,238,50,66,134,230,36,204,220,229,30,51,209,69,150,11,100,1,2,137,176,173,86,222,200,84,196,194,98,117,131,246,151,201,175,237,2,171,143,226,11,55,238,132,64,173,250,218,142,64,199,86,125,153,115,180,123,158,104,13,166,38,87,147,98,106,10,95,12,77,42,12,82,104,23,191,212,228,12,199,125,58,130,124,122,65,202,137,55,92,199,233,244,206,154,104,128,156,100,112,105,173,32,189,105,111,213,84,198,151,41,209,208,17,153,169,11,90,77,217,47,14,84,182,117,96,234,193,118,225,142,205,203,242,47,245,246,0,211,140,199,194,154,5,228,61,102,10,11,244,92,163,110,14,250,15,177,64,125,122,120,127,33,142,140,232,3,99,9,24,106,151,147,182,69,250,122,179,206,119,207,51,30,6,139,166,46,37,49,231,157,166,249,155,105,60,82,171,115,94,228,160,153,142,96,134,177,75,133,0,10,209,91,204,120,148,146,135,251,191,184,7,189,70,231,111,235,156,172,49,30,212,147,128,10,237,183,121,145,98,175,137,166,16,2,201,10,243,28,117,169,92,125,67,114,94,166,24,168,141,74,106,2,178,232,171,45,141,78,158,101,85,192,29,140,138,66,144,215,88,233,90,153,74,215,206,166,215,52,215,49,70,229,154,138,197,49,42,90,57,254,64,140,138,98,118,133,26,62,127,4,187,116,151,19,152,166,230,50,19,54,120,246,52,182,200,50,220,150,169,37,210,250,234,108,79,100,174,11,153,223,84,224,105,166,195,105,196,236,138,76,2,83,134,97,126,4,197,167,80,166,53,205,95,211,243,0,83,168,248,220,45,103,17,89,225,41,20,122,25,181,198,116,223,195,43,48,140,85,9,166,162,189,140,64,155,121,216,59,136,64,212,7,115,204,106,230,17,129,57,17,196,253,206,34,1,5,35,40,152,55,198,230,24,190,66,247,239,35,99,68,43,120,1,63,184,231,77,38,197,115,53,141,151,41,93,73,239,128,105,206,57,30,20,100,11,72,134,247,23,205,22,83,184,75,217,71,25,72,38,164,175,3,202,219,165,147,63,49,41,173,45,136,21,121,2,82,90,91,16,43,242,90,25,37,137,50,164,34,189,147,40,47,221,146,47,20,81,39,223,147,21,121,66,17,177,104,14,86,164,219,151,39,20,25,91,149,166,15,235,243,235,71,105,109,65,172,200,19,10,99,68,203,147,138,156,13,158,25,66,145,30,221,114,207,179,123,154,166,34,53,244,55,205,220,246,188,67,191,78,118,25,209,150,69,51,7,36,150,69,47,156,57,209,252,160,136,123,50,104,150,147,238,137,4,100,34,200,186,194,201,88,33,21,191,48,106,81,126,170,17,179,91,132,147,50,39,130,180,44,21,25,177,227,62,202,212,105,44,92,162,20,221,235,242,175,57,92,21,179,99,243,93,149,156,148,251,162,153,99,136,233,195,48,7,76,57,245,164,97,46,75,186,171,195,98,172,55,93,28,67,210,194,82,90,91,32,67,102,184,45,105,9,185,155,219,18,231,199,195,186,45,219,177,49,121,126,9,73,182,50,75,64,74,107,83,182,106,23,113,94,102,9,72,114,141,215,61,25,146,22,144,100,62,121,134,132,228,184,48,25,19,119,45,75,198,82,196,84,34,125,198,130,25,115,60,216,78,10,104,75,67,19,45,216,153,74,139,65,245,12,82,94,100,144,146,90,149,176,157,4,218,74,131,203,11,22,238,68,125,160,216,248,34,29,12,73,47,164,121,202,206,111,126,195,65,188,221,210,204,180,204,92,155,124,211,79,251,69,115,174,116,175,153,147,14,185,107,124,59,234,57,133,64,253,144,241,242,157,232,179,90,132,100,166,161,141,101,26,242,171,92,102,35,85,76,253,91,139,228,77,173,187,150,113,69,25,39,148,220,148,111,100,11,84,81,100,148,177,163,50,117,67,16,210,130,174,78,42,158,73,5,40,70,196,118,219,40,99,41,118,69,45,80,180,72,25,23,248,155,233,29,103,230,42,35,115,169,129,225,97,36,92,55,49,224,12,10,73,244,98,134,204,86,122,84,200,89,20,209,50,210,73,121,78,124,108,127,50,28,148,243,236,73,166,171,91,144,93,81,120,95,241,61,189,61,169,64,146,209,116,150,19,12,127,224,80,130,109,70,29,23,193,241,208,92,170,27,153,94,20,201,198,206,201,168,4,171,239,177,244,68,114,220,158,33,226,139,28,244,91,230,120,183,93,142,134,76,89,104,94,46,23,20,235,187,179,72,114,185,149,10,51,239,196,103,168,73,41,42,200,217,226,162,60,123,2,50,61,143,54,147,177,145,227,85,136,179,243,103,8,75,119,191,230,187,88,134,48,41,166,233,5,26,59,83,195,10,114,85,230,182,17,195,144,253,23,95,22,157,186,97,219,92,207,223,110,38,223,200,50,133,210,167,53,51,135,83,88,161,76,223,66,185,148,210,60,212,51,80,150,214,226,56,149,211,104,162,220,142,168,107,12,166,82,157,245,213,64,96,231,202,114,212,38,51,26,96,25,64,107,81,139,27,166,174,200,62,40,68,215,60,146,86,186,45,149,46,161,15,54,74,107,3,236,160,30,243,61,171,119,9,29,108,67,134,162,63,60,159,48,210,243,225,213,62,162,214,177,107,33,64,39,174,85,225,127,205,81,113,31,50,8,94,131,194,229,75,155,165,210,32,112,173,226,53,222,254,252,224,253,198,38,248,250,155,254,132,33,112,51,103,163,42,251,100,131,227,219,216,228,85,231,110,151,120,135,199,158,83,249,105,101,143,140,61,31,81,42,8,154,11,208,102,105,237,118,179,180,230,35,22,248,110,241,150,243,170,186,51,103,87,66,110,48,62,155,120,136,130,215,96,12,47,208,198,215,223,68,212,119,221,96,124,224,14,72,25,212,55,11,194,27,211,97,46,184,119,136,82,56,68,18,98,163,89,20,228,144,104,136,95,127,131,93,134,252,1,180,208,205,237,77,105,109,227,75,151,92,185,39,104,136,174,55,55,106,155,101,144,245,84,171,160,214,1,28,67,69,3,174,68,245,74,107,27,159,189,193,200,177,79,2,7,209,205,13,23,59,89,112,170,85,80,79,2,137,170,9,32,14,129,108,38,144,70,10,72,88,141,3,217,39,65,223,65,83,161,84,171,160,153,4,98,84,227,80,14,92,214,108,204,36,165,149,132,18,85,83,64,218,173,153,64,182,51,128,168,106,28,200,249,108,82,170,85,208,78,2,57,143,147,114,62,155,150,106,21,236,100,65,49,104,57,45,68,203,139,36,148,211,56,45,167,133,104,121,153,5,197,160,229,13,190,70,246,116,98,184,196,165,228,214,172,23,194,153,78,14,135,147,33,186,81,61,209,170,217,4,113,56,41,233,61,77,18,116,58,155,34,14,40,37,193,167,73,138,62,39,196,153,46,125,2,80,74,136,195,122,130,26,230,99,119,56,171,179,234,41,33,54,234,9,90,38,12,209,217,246,33,37,198,81,61,14,133,27,211,2,45,74,137,113,88,143,3,81,38,116,86,135,167,164,216,172,199,225,156,32,15,65,134,166,89,61,14,39,37,199,177,122,130,32,232,205,104,148,48,123,41,73,214,245,56,140,93,119,82,4,70,74,138,117,61,97,57,3,31,50,76,220,233,13,106,164,36,56,86,143,3,58,195,99,68,25,28,79,105,22,7,148,146,224,120,61,14,201,86,160,189,126,136,37,9,142,67,106,117,192,144,144,161,131,42,98,184,235,7,131,176,56,135,194,52,92,175,31,225,136,195,225,80,182,211,80,194,210,130,24,68,45,31,123,140,248,94,95,75,195,177,199,145,132,109,228,96,218,105,48,241,194,41,88,199,46,34,131,4,36,73,210,78,26,150,89,56,5,73,140,167,153,144,94,164,33,153,133,75,183,5,61,9,27,121,7,246,117,232,73,52,27,55,165,53,62,211,203,114,17,162,209,189,50,150,28,232,176,137,135,122,46,28,35,176,245,251,83,245,171,81,158,229,49,84,6,124,220,159,6,209,116,12,154,229,28,231,33,130,103,11,23,96,26,192,152,147,208,42,103,123,18,6,68,193,160,105,0,205,129,113,187,156,237,83,196,225,181,91,51,224,133,3,64,187,156,237,94,24,240,130,153,4,198,220,136,157,114,182,175,145,128,56,157,196,152,75,241,162,156,237,119,24,16,233,76,26,99,238,197,203,114,182,15,146,128,56,157,198,152,171,81,175,149,51,253,17,83,18,229,16,62,85,22,99,163,124,189,94,206,243,78,226,64,167,211,25,31,241,235,141,114,158,171,18,181,189,0,169,9,143,164,222,44,103,123,46,41,176,51,152,154,160,182,85,206,246,99,12,176,125,66,156,105,32,13,79,165,190,93,206,246,102,76,42,133,79,50,149,70,211,107,169,183,203,217,190,141,73,33,247,79,166,146,104,56,48,245,157,114,182,151,99,0,228,147,201,105,240,12,87,166,254,178,156,237,238,24,224,124,229,108,76,3,153,112,72,26,82,222,211,14,144,105,206,161,55,213,148,135,158,73,67,9,250,52,237,129,238,100,26,176,200,69,105,72,1,79,123,66,166,17,87,227,254,84,51,30,119,88,26,82,192,211,206,145,1,54,116,33,166,193,77,250,47,181,114,142,199,100,136,89,229,10,57,78,239,130,79,166,123,62,159,77,79,67,96,206,185,235,229,28,47,42,214,157,21,204,208,120,170,128,154,83,112,13,51,165,68,186,67,43,23,104,50,55,180,148,254,132,208,46,161,19,76,87,31,19,94,163,21,58,88,83,250,179,98,17,151,38,220,130,124,231,80,195,76,233,80,28,166,51,55,192,148,246,36,1,162,121,33,166,84,40,14,113,56,47,137,205,148,26,37,1,206,75,98,51,165,65,113,136,216,157,23,224,244,185,70,197,37,172,55,7,80,57,68,52,103,204,59,138,8,144,49,47,208,80,83,58,147,128,58,75,132,50,64,166,20,39,5,114,70,15,101,192,76,41,79,2,230,44,49,202,0,153,210,157,20,200,57,200,84,29,159,82,159,4,204,43,204,70,115,244,188,28,201,155,41,21,178,49,133,125,7,217,29,116,205,144,107,163,76,56,201,217,155,130,214,74,233,15,30,186,196,159,23,152,244,9,90,41,213,241,209,183,1,158,5,45,62,25,108,200,121,88,43,165,53,62,231,217,84,64,177,185,160,182,220,173,148,166,72,64,5,237,117,75,246,229,215,173,86,167,213,250,6,96,10,216,8,1,26,244,183,28,76,25,24,16,31,140,17,27,17,27,144,128,121,1,235,113,184,243,84,195,174,81,171,169,106,53,115,107,137,246,83,76,92,16,54,160,180,214,148,78,212,215,205,151,157,86,115,86,61,205,193,112,104,255,186,214,105,190,204,174,53,224,156,48,48,221,170,244,11,118,49,219,216,4,55,5,230,218,170,232,109,209,188,141,6,93,90,195,3,240,102,86,113,240,195,215,192,197,142,200,206,200,4,73,105,237,86,84,253,97,148,111,56,119,41,28,160,174,43,180,164,96,34,71,231,47,190,174,125,83,233,94,123,196,103,200,7,175,129,72,6,93,2,35,253,80,6,152,255,220,52,223,9,28,107,244,10,51,107,4,46,65,231,53,184,172,196,210,11,175,0,150,101,44,72,17,168,117,248,159,58,193,243,191,93,86,40,131,12,133,159,235,169,207,248,59,180,7,173,81,84,164,145,44,18,184,194,27,19,40,41,255,102,163,1,12,28,22,43,231,98,135,255,188,45,201,255,207,193,148,250,226,152,18,165,75,158,58,83,26,11,99,138,153,254,121,234,92,105,46,140,43,70,222,230,169,51,165,181,72,166,232,44,203,83,103,202,246,194,152,114,254,140,68,165,189,80,174,60,23,89,217,89,24,87,78,159,145,172,188,88,40,87,158,139,172,188,92,160,7,103,100,199,159,58,91,234,139,244,108,141,100,255,147,231,203,226,156,219,211,231,37,48,139,115,112,79,159,151,196,44,206,199,141,150,187,60,121,166,44,206,199,53,151,239,60,121,182,44,206,203,53,150,35,61,121,174,44,206,203,141,150,87,61,121,166,44,206,201,141,45,23,123,242,124,89,156,155,27,95,254,246,228,25,179,56,79,55,92,206,247,212,121,210,88,156,151,27,46,79,124,242,60,89,156,135,27,95,110,249,228,25,179,56,15,55,177,124,244,83,228,204,109,145,205,48,102,30,68,36,234,190,242,161,231,33,63,107,27,70,108,11,69,79,68,246,213,250,205,228,55,25,224,206,249,40,2,50,249,223,218,173,156,111,231,120,74,197,115,60,165,230,233,180,154,167,211,106,170,9,222,180,175,249,88,7,83,43,159,14,166,214,230,51,133,188,154,194,95,238,229,85,228,110,99,206,55,238,60,229,124,210,67,101,206,231,119,208,203,249,178,235,78,242,164,32,190,26,58,249,57,185,202,121,94,137,229,51,144,2,34,107,204,46,122,221,49,196,49,174,154,31,191,32,148,185,112,140,242,190,31,120,249,95,46,91,83,190,181,243,190,157,251,120,202,167,19,52,200,251,186,107,219,62,162,52,183,114,128,237,188,111,95,33,199,49,183,83,229,32,112,188,17,236,35,150,139,66,20,112,131,113,110,129,67,114,133,124,110,203,242,10,156,81,100,81,230,223,181,243,183,11,117,126,52,135,74,116,95,236,67,188,247,226,159,218,38,129,108,226,33,112,13,40,243,3,139,221,220,150,214,72,192,248,136,16,229,162,57,117,159,7,216,177,145,207,41,120,131,29,212,49,62,239,35,106,25,159,215,222,146,247,208,186,128,67,244,30,178,81,7,248,104,224,32,139,9,40,199,131,141,235,155,219,205,202,251,139,33,255,184,33,168,91,59,145,155,255,228,98,250,78,241,221,130,162,242,81,48,230,22,128,118,228,126,130,186,126,169,166,15,226,125,163,25,22,213,75,10,104,7,180,244,203,83,228,95,98,75,22,173,241,151,183,252,159,183,114,235,94,199,216,60,81,120,191,31,175,191,143,60,228,218,200,181,38,7,174,141,174,57,164,194,171,252,121,125,189,129,209,160,96,142,45,145,28,130,177,103,81,3,41,46,141,130,4,205,173,8,68,1,18,174,153,6,112,91,17,114,177,177,89,90,155,189,42,226,53,32,1,171,240,114,115,108,120,5,175,165,131,48,207,78,204,130,21,162,13,23,188,194,109,233,7,171,231,119,242,161,65,127,76,108,110,58,171,92,94,182,132,116,88,196,169,50,68,89,245,243,243,131,195,253,123,227,168,213,106,181,118,171,37,254,91,171,213,146,255,21,127,215,91,219,245,90,125,187,209,174,183,127,80,171,239,108,239,108,255,0,212,22,210,194,25,79,64,25,244,127,80,171,249,132,176,105,229,102,125,79,54,238,137,60,211,251,255,164,187,187,255,174,91,25,219,247,194,49,171,255,235,173,118,188,255,27,181,102,109,213,255,75,121,120,167,255,250,47,254,236,251,95,253,253,247,127,247,199,223,255,233,127,255,205,223,255,237,175,255,225,31,126,251,151,255,246,55,255,239,95,252,250,207,127,245,219,127,252,215,223,255,234,95,254,143,63,254,229,247,255,244,255,252,243,127,251,219,223,254,245,159,252,246,151,127,246,155,255,252,255,127,255,171,127,85,42,109,1,203,243,254,231,63,254,210,250,189,223,203,172,255,155,191,249,247,178,206,106,116,249,100,159,233,250,111,121,222,2,198,128,25,250,95,111,52,210,250,191,211,88,233,255,50,30,203,82,14,161,131,251,62,244,39,27,37,238,7,139,85,216,175,193,186,101,73,47,82,20,89,47,139,111,54,242,196,212,173,164,253,246,245,170,16,157,78,170,228,55,229,210,102,169,84,12,3,145,139,196,11,97,170,138,66,157,220,122,5,241,66,215,37,12,206,129,22,122,184,147,87,169,32,206,17,99,94,113,100,169,210,5,177,208,43,56,28,34,191,24,34,85,184,147,85,169,32,190,248,220,98,22,66,93,186,147,89,77,160,124,108,173,248,221,121,166,218,255,62,159,223,86,232,232,158,56,102,250,255,205,86,218,254,183,87,246,127,25,207,143,126,88,237,99,183,218,135,116,84,42,245,225,119,200,1,162,215,65,165,82,121,108,218,86,207,195,63,249,250,207,77,245,114,230,255,141,122,51,61,255,111,173,244,127,25,143,39,131,217,27,42,57,217,187,196,20,247,177,131,217,132,143,221,235,213,106,244,162,227,5,125,7,91,235,223,108,150,74,83,252,129,148,27,72,125,43,225,8,136,205,125,171,65,255,83,120,166,235,63,244,240,195,207,255,106,219,25,243,191,237,149,254,47,229,89,188,254,231,205,144,210,102,192,40,153,180,6,243,79,141,68,129,63,176,200,184,39,55,33,247,244,38,228,106,181,19,29,102,149,49,187,153,210,148,20,146,116,27,120,145,167,108,202,102,235,127,170,151,230,198,49,75,255,91,237,122,66,255,155,141,250,42,254,179,148,135,78,92,6,175,185,176,139,190,109,174,191,42,149,148,77,144,123,240,161,135,95,149,74,120,236,17,159,201,145,91,72,133,33,247,175,194,175,82,243,170,161,230,69,122,23,22,45,201,128,13,24,146,158,70,163,124,134,202,208,39,129,39,229,46,46,138,94,191,58,36,161,64,174,191,210,48,254,8,94,66,19,138,69,198,21,134,92,11,185,172,18,185,24,253,96,80,65,215,140,227,150,27,237,51,14,79,96,35,162,143,41,0,55,66,141,191,96,76,44,20,3,188,161,224,53,216,174,53,106,245,87,207,47,81,58,91,255,163,158,190,43,142,25,250,191,93,107,110,39,244,191,222,110,174,230,255,75,121,10,234,255,99,106,173,58,228,49,82,73,169,161,213,42,56,69,14,178,24,5,80,31,221,193,8,184,26,97,107,4,216,8,83,224,243,194,208,243,28,140,104,69,213,209,85,79,208,0,249,188,252,215,84,0,33,254,55,95,43,187,0,61,92,217,39,86,48,70,46,11,151,210,86,194,98,226,24,14,197,54,27,49,136,29,5,92,158,3,7,116,65,240,26,212,95,149,52,190,125,196,144,63,198,46,146,103,122,156,159,28,2,15,50,134,124,23,96,10,198,144,89,35,100,131,254,36,162,156,86,192,25,255,91,23,179,160,11,250,72,195,11,40,178,193,21,102,35,0,221,9,32,3,1,245,102,136,216,47,188,128,253,194,35,148,253,194,70,14,98,232,23,30,135,125,171,56,68,43,96,23,88,1,101,100,172,222,104,128,18,60,176,209,0,187,200,6,1,229,109,225,64,127,34,139,255,68,30,61,34,155,74,92,68,6,33,101,55,37,227,212,212,119,208,163,156,175,95,156,157,189,7,111,187,103,21,112,206,73,229,76,115,48,101,28,42,228,54,24,49,241,55,118,7,196,31,11,54,3,216,39,1,51,97,249,136,146,192,183,116,239,25,76,30,34,6,94,131,134,226,111,22,234,247,231,38,106,31,121,14,180,4,242,16,106,10,168,23,112,160,205,105,64,143,79,77,168,150,143,32,139,3,5,196,7,30,242,121,163,100,83,1,180,120,227,210,200,8,229,216,90,83,176,237,119,15,187,103,93,3,159,232,209,25,141,144,189,206,71,172,105,237,216,61,219,251,194,0,28,120,118,178,33,105,130,185,28,129,215,160,29,135,123,54,66,90,160,12,129,14,52,100,234,33,11,15,38,138,23,2,185,214,213,17,100,188,168,75,98,125,142,93,203,9,108,100,3,236,10,241,251,168,160,126,148,242,87,6,52,176,70,0,82,240,69,119,119,191,204,217,189,254,217,58,111,152,131,224,37,226,85,76,104,38,194,192,149,196,96,69,90,168,105,21,209,136,43,236,216,91,22,244,109,105,55,100,35,6,129,99,130,19,45,82,235,233,100,3,60,159,92,98,27,1,139,184,12,185,140,19,242,21,234,131,141,47,206,222,29,110,2,203,193,200,101,134,248,238,9,78,113,75,246,94,171,181,228,221,107,240,226,149,40,117,27,154,12,78,148,152,137,40,237,246,209,183,1,162,76,29,1,116,53,34,20,1,113,212,157,180,32,158,135,132,1,228,69,69,179,85,121,13,174,79,236,137,224,215,199,207,62,202,227,142,160,231,137,126,113,156,56,108,209,39,192,130,30,11,124,109,148,16,239,221,145,134,165,123,218,68,23,194,39,99,204,152,226,49,7,52,130,151,178,251,39,49,186,68,133,164,89,62,58,62,235,118,84,107,7,200,231,232,101,115,199,1,175,129,128,231,35,202,249,12,153,40,197,136,183,229,160,75,228,36,152,164,225,233,177,131,77,60,20,179,210,28,57,120,13,118,34,11,45,253,63,232,84,50,24,79,61,226,82,84,148,243,165,200,124,201,122,162,165,224,171,17,114,53,115,202,162,48,114,25,246,13,248,154,218,43,236,56,188,177,92,139,52,48,72,205,158,53,1,103,178,240,236,62,44,148,208,103,242,80,23,236,41,102,214,27,17,55,119,109,27,75,126,42,233,192,174,141,221,33,85,154,135,194,97,178,2,142,16,229,226,18,150,224,116,106,48,66,16,137,203,32,118,185,253,248,8,67,176,61,93,254,163,62,19,107,132,198,20,57,151,136,130,13,101,91,202,26,12,71,232,34,57,250,140,225,4,16,215,153,112,86,16,23,1,217,118,27,33,111,83,182,78,31,110,26,57,28,25,88,121,115,197,124,160,196,27,59,205,2,138,17,149,35,86,101,4,59,46,145,223,175,132,158,77,218,42,220,100,27,1,76,51,160,24,61,114,129,93,59,238,119,156,41,205,77,185,24,10,78,10,132,40,44,134,214,103,55,215,89,61,233,103,250,252,79,252,186,119,4,120,86,252,167,217,106,36,227,191,59,173,85,252,103,41,207,3,229,127,178,150,229,100,231,129,116,209,98,17,224,59,4,120,31,155,195,159,246,83,68,255,211,221,52,31,142,217,249,159,228,250,143,230,206,106,253,223,114,158,172,248,207,60,225,92,51,86,116,239,56,145,134,186,132,248,174,242,118,160,131,33,21,225,221,154,12,239,230,193,48,79,178,141,131,24,146,30,131,67,9,99,187,246,212,220,166,233,250,175,214,4,222,211,3,152,57,254,55,107,201,248,111,163,217,92,233,255,50,158,197,143,255,89,235,72,211,67,191,42,181,26,245,31,249,41,166,255,177,222,154,27,199,12,253,175,215,90,169,241,191,81,171,173,244,127,25,207,61,199,255,133,14,255,74,202,150,227,0,156,74,100,34,190,163,16,139,49,188,94,11,195,58,140,128,33,114,195,175,127,68,137,27,134,108,204,234,49,119,128,97,230,32,5,169,249,202,252,162,194,208,242,83,43,246,73,115,150,55,90,126,223,126,21,143,69,41,124,239,161,15,199,192,227,255,82,85,178,45,200,77,208,37,203,197,8,83,246,185,46,1,247,9,145,81,95,236,35,91,198,123,98,244,136,209,64,102,67,110,31,91,70,87,207,195,61,211,237,127,164,100,247,193,49,221,254,183,106,219,141,148,255,87,91,173,255,91,206,51,43,255,127,95,163,62,175,49,175,80,6,93,27,250,118,197,34,227,49,113,19,245,73,192,144,223,179,28,72,169,246,55,207,78,222,239,189,87,136,57,245,42,232,61,134,67,108,169,44,13,25,136,182,0,77,95,9,185,193,24,156,249,158,245,78,148,226,118,146,219,123,94,198,38,72,230,191,2,138,100,164,92,192,40,3,204,194,176,190,206,136,245,249,248,176,101,17,27,1,70,136,83,2,128,19,211,219,239,190,217,61,63,60,235,29,29,31,117,193,107,80,187,174,213,68,64,62,131,178,16,92,140,60,5,231,221,238,219,131,189,222,135,221,195,115,9,230,101,179,166,135,38,14,199,134,12,130,129,207,217,32,78,57,81,233,155,24,40,192,25,142,152,168,114,69,68,57,10,160,143,128,21,248,62,114,153,51,1,52,240,196,249,90,118,135,151,170,87,50,97,139,36,177,203,125,125,226,162,45,157,248,217,50,127,108,242,234,141,252,234,148,249,8,142,35,214,239,67,6,223,240,34,103,188,196,141,110,244,249,209,238,201,207,122,111,78,118,223,197,120,39,190,157,158,157,116,119,223,153,31,235,38,67,84,122,215,74,50,133,51,68,98,23,99,91,72,27,175,247,134,4,126,1,182,124,60,56,58,56,251,40,171,117,192,155,131,159,126,209,221,221,239,158,128,223,19,77,57,21,192,15,92,204,222,33,6,69,249,253,221,179,221,204,242,34,87,182,209,15,40,118,17,165,128,34,31,67,7,127,135,108,65,152,96,226,199,55,221,238,254,231,187,123,95,206,64,248,6,33,251,115,104,93,112,164,96,131,249,152,143,252,200,230,109,133,12,13,39,29,48,194,195,81,213,33,87,224,10,50,228,171,84,23,116,109,192,240,24,249,18,217,222,225,241,105,119,6,166,61,135,80,36,218,22,118,159,34,33,167,3,167,118,93,143,51,51,236,191,204,18,156,125,178,68,35,167,132,230,145,44,213,204,41,37,26,39,139,180,76,81,209,238,146,76,206,9,251,66,6,74,72,98,157,29,58,86,233,126,214,102,67,231,179,199,252,157,177,158,133,19,20,171,116,34,11,138,186,170,82,79,84,210,25,59,51,103,92,0,154,44,169,192,169,84,172,130,215,48,13,206,21,118,109,114,5,40,254,14,169,5,23,114,17,132,50,99,62,178,16,190,148,171,161,100,102,214,181,145,95,2,64,222,227,42,174,22,234,73,24,61,1,67,175,145,209,106,167,68,88,46,226,49,77,145,230,12,151,108,89,30,13,213,217,74,85,238,77,87,43,149,114,232,107,138,215,6,84,173,204,210,80,90,196,151,109,180,197,42,150,143,156,23,123,114,205,69,215,229,22,152,11,225,199,136,104,181,30,67,92,227,20,46,179,209,203,85,200,216,243,17,165,57,228,42,85,140,8,30,126,135,189,42,117,161,231,77,170,21,78,178,26,30,4,7,21,249,115,18,46,9,200,161,25,241,6,113,83,37,22,241,68,66,155,39,104,119,150,98,83,32,149,48,239,65,199,65,190,152,44,164,155,36,177,73,188,29,189,60,208,115,212,7,113,33,85,133,34,255,18,249,242,111,25,37,82,11,102,196,171,50,104,1,138,134,99,228,50,90,2,64,220,115,10,44,137,211,208,2,65,5,122,48,42,190,174,132,199,142,137,223,223,196,73,65,166,2,29,232,146,97,26,94,150,153,69,87,85,185,58,21,19,113,53,142,55,68,43,110,226,74,168,149,185,236,34,26,219,161,75,61,232,139,149,70,252,239,49,150,98,28,55,20,213,106,184,74,138,249,98,217,91,25,216,19,36,86,8,160,73,25,12,125,56,41,3,24,176,17,114,153,34,188,12,198,129,195,240,22,114,47,177,79,92,222,67,101,64,17,3,178,219,16,179,42,115,201,184,58,158,43,33,226,170,81,153,106,105,74,244,5,154,108,73,216,30,196,190,217,110,103,162,91,46,22,25,41,27,38,164,252,138,248,23,74,126,194,97,220,198,151,88,174,38,227,214,237,138,240,185,51,163,29,89,172,46,126,233,123,214,76,252,140,128,62,154,3,45,112,224,4,249,101,9,86,12,176,137,53,68,23,104,18,46,192,225,51,14,166,151,111,126,20,158,243,199,143,178,106,227,190,20,133,142,69,22,65,225,71,11,186,162,111,49,227,245,48,163,200,25,104,15,215,71,220,243,230,99,128,88,212,36,136,85,164,66,207,219,250,248,81,218,63,69,183,68,112,68,24,146,107,142,18,29,135,93,73,100,143,55,37,92,215,148,223,10,54,242,73,48,28,9,106,175,70,196,65,192,193,238,69,25,120,14,130,84,184,203,156,74,11,250,104,16,56,206,68,56,150,186,85,92,62,199,208,251,223,101,12,163,44,85,235,247,77,252,210,158,190,50,12,106,206,96,123,15,139,106,12,202,202,164,118,125,159,248,128,143,81,115,41,208,9,98,123,196,22,202,35,117,199,23,107,94,235,166,202,248,136,242,161,211,164,252,106,132,228,194,73,110,166,192,0,98,39,50,180,136,83,210,27,211,161,90,224,99,204,150,138,49,32,225,152,102,48,33,230,147,42,6,96,215,242,121,247,217,166,39,18,217,4,195,181,232,137,162,220,246,200,150,70,99,159,197,61,80,59,203,167,207,152,213,25,78,107,232,155,138,197,100,254,24,58,18,20,5,129,139,109,236,35,75,173,82,27,56,228,42,225,66,134,206,163,102,121,247,218,66,114,50,170,96,244,99,32,212,12,39,14,228,164,123,218,61,75,182,102,6,187,179,90,39,23,28,59,68,172,203,86,152,210,236,15,29,117,221,102,142,77,51,77,65,228,64,2,31,149,101,35,196,26,56,228,218,98,233,166,124,3,29,39,20,58,241,70,155,235,80,246,22,43,210,141,123,136,180,20,230,231,63,112,2,16,31,59,87,131,231,106,240,124,132,193,51,18,56,20,154,0,221,75,161,111,43,11,213,192,24,65,151,114,133,178,16,165,101,64,216,8,249,234,37,87,226,192,71,161,33,224,14,112,79,90,131,182,105,40,47,145,79,77,163,152,182,245,34,244,247,65,21,11,131,16,239,79,142,207,142,123,31,234,64,154,111,99,28,225,38,36,54,138,164,65,242,217,135,57,110,156,207,8,124,149,245,166,5,64,39,174,37,4,6,242,191,226,33,173,189,221,195,67,115,48,57,118,209,21,156,232,50,199,71,221,175,118,195,66,245,172,88,197,220,246,44,138,114,70,38,229,129,98,157,107,107,32,17,233,220,151,102,83,17,31,22,255,89,247,224,232,109,239,93,247,244,116,247,109,215,140,1,241,198,74,147,155,172,115,118,178,187,215,141,87,9,71,140,119,194,244,118,35,211,155,172,252,238,252,240,236,160,215,61,250,16,7,16,218,206,161,143,237,100,157,183,39,7,251,241,226,47,116,241,83,196,142,198,16,37,107,156,118,207,142,118,223,197,137,172,199,228,46,156,211,155,189,40,98,129,34,30,169,54,187,196,5,146,139,30,69,242,183,25,106,168,86,193,46,211,203,248,117,103,193,161,143,144,218,85,195,65,169,253,9,18,174,15,221,161,192,90,219,170,55,118,146,125,27,217,255,72,5,146,161,21,45,55,94,63,174,98,221,163,189,227,253,152,147,244,71,86,200,150,255,115,175,27,21,8,187,89,228,81,117,137,211,227,163,168,72,216,173,3,7,178,126,48,24,136,48,148,40,248,230,112,247,236,243,243,55,111,186,39,81,241,112,212,103,232,154,113,247,165,143,185,166,234,42,71,199,199,239,163,194,97,143,95,143,67,225,253,233,187,195,168,64,104,221,216,200,199,3,22,74,223,23,39,7,111,206,162,98,49,243,164,35,73,196,159,179,95,143,72,44,10,101,116,174,209,5,81,144,72,115,63,94,45,153,111,216,59,126,247,254,164,123,122,106,246,198,240,59,236,133,114,253,243,131,247,102,161,176,71,100,108,107,99,31,121,62,178,196,149,2,170,179,163,129,227,163,148,243,163,221,247,239,127,22,250,199,10,212,199,106,236,235,231,135,199,123,95,70,31,213,48,250,57,178,160,48,51,124,228,27,18,57,172,242,191,45,207,19,24,148,119,202,223,247,29,98,93,128,49,177,17,21,115,52,238,97,95,34,103,82,46,133,187,57,184,55,2,125,164,54,136,140,61,200,112,223,65,101,81,221,242,9,165,91,14,116,135,1,183,155,220,228,83,57,124,142,225,5,2,99,76,25,188,64,52,84,94,73,182,193,152,80,14,191,115,112,40,239,63,63,60,248,220,44,212,140,115,47,233,253,103,114,202,148,67,85,77,180,53,81,43,206,65,83,54,157,239,90,106,234,165,106,28,254,188,165,67,221,81,241,182,89,60,134,128,23,79,65,223,209,34,253,155,191,249,191,127,243,87,255,229,215,255,233,255,250,205,191,248,119,191,254,243,191,253,254,63,254,233,111,255,242,239,126,251,203,63,251,254,159,254,242,215,255,230,175,126,251,215,127,242,235,255,240,203,127,254,175,255,95,52,125,22,119,152,136,49,33,49,129,73,187,119,145,123,32,58,36,146,115,53,41,208,34,174,220,5,77,240,193,209,135,227,47,187,189,211,243,189,189,132,100,203,16,223,22,197,182,233,140,168,97,1,98,55,233,191,82,116,137,124,62,253,131,12,13,137,143,81,232,200,86,162,73,150,143,28,46,255,74,208,26,149,4,213,137,239,205,10,248,54,64,1,18,233,20,18,8,27,68,46,145,239,16,104,235,162,178,100,171,2,42,149,74,6,229,33,102,163,9,233,82,54,18,76,22,101,162,49,231,228,67,247,164,183,223,229,134,169,215,61,57,209,139,59,146,188,113,115,235,74,163,166,234,134,66,159,104,114,138,48,153,35,48,136,211,94,196,8,94,34,0,141,73,141,220,14,45,194,159,0,143,61,7,133,91,170,19,132,28,29,243,63,14,246,194,118,232,134,204,135,43,162,124,6,182,55,231,71,123,26,85,216,110,213,137,85,221,131,85,7,143,49,67,126,54,7,116,48,158,215,178,129,232,124,55,73,110,2,239,217,193,187,238,241,249,153,230,183,217,70,13,13,211,80,128,56,212,20,196,112,54,98,84,176,49,181,160,111,11,81,51,209,29,127,232,158,28,30,239,238,107,124,141,108,124,124,214,192,152,147,137,46,1,241,240,224,221,193,89,55,4,216,124,101,78,219,35,128,83,56,2,108,174,45,50,207,196,39,33,98,134,162,57,159,192,246,230,252,240,176,119,120,112,244,101,146,113,173,44,19,64,39,148,161,113,166,152,159,254,236,244,172,251,78,213,110,214,95,229,200,177,110,66,124,122,47,166,42,200,206,4,188,123,126,246,133,2,219,154,9,86,44,218,66,92,158,96,192,8,119,209,45,62,189,49,50,7,249,136,62,236,30,30,236,239,158,105,245,216,14,145,201,13,198,139,49,130,218,136,165,108,160,139,152,176,227,2,186,235,202,120,87,218,20,230,24,209,86,5,248,36,96,114,195,168,97,18,183,77,147,168,113,79,85,181,44,217,50,24,160,121,182,119,120,208,61,58,211,35,71,92,118,196,234,190,121,1,23,18,90,133,53,79,104,235,209,156,37,155,157,169,150,155,4,36,203,37,144,238,29,31,29,117,247,66,84,245,80,60,242,71,151,152,224,100,140,16,10,114,108,132,168,135,38,43,198,156,140,177,73,213,142,143,77,141,70,150,212,154,214,118,166,177,205,50,87,249,18,16,55,87,245,60,123,149,54,184,38,125,220,224,166,44,172,66,144,176,176,245,184,101,226,163,158,150,252,152,110,154,32,78,142,207,207,248,72,44,1,52,51,21,123,166,192,196,65,30,117,207,190,58,62,249,82,195,108,101,194,12,83,31,119,50,75,10,83,194,44,213,35,187,20,120,218,157,87,174,187,224,161,36,30,217,101,128,160,239,76,128,5,93,11,57,14,84,246,68,246,72,110,187,246,118,143,246,186,135,81,127,182,115,26,6,109,115,253,81,22,221,39,221,221,125,229,53,43,88,59,33,172,116,92,43,54,202,104,39,191,90,5,227,57,237,107,17,51,218,200,48,163,32,180,176,87,62,102,225,68,73,180,49,81,134,219,90,222,254,172,34,25,86,55,221,50,177,80,184,160,184,169,185,141,118,170,98,82,215,136,162,58,217,72,210,238,174,36,89,7,187,208,181,133,144,77,229,162,21,225,136,101,163,125,119,250,182,215,253,233,94,183,187,47,213,61,116,174,102,225,55,108,222,148,86,197,61,228,70,150,127,109,172,44,67,133,96,198,172,98,35,178,138,105,160,170,195,103,1,252,234,228,128,235,224,209,190,112,202,4,141,185,165,184,201,122,115,120,252,85,232,195,53,166,22,23,41,176,176,108,115,106,217,132,151,214,204,118,211,100,195,132,148,206,106,151,80,83,213,172,237,188,102,137,66,49,50,183,243,154,36,225,189,123,127,246,179,176,104,94,139,68,209,68,131,182,91,249,54,194,180,64,207,203,70,164,91,118,7,27,145,57,50,53,107,153,6,124,138,141,72,23,43,110,47,20,9,57,246,162,89,159,69,203,12,123,145,229,47,53,51,253,165,226,246,34,203,139,106,102,123,81,197,236,133,2,104,218,139,102,218,94,196,74,37,236,69,51,109,47,98,197,77,69,108,166,237,69,172,108,92,189,154,145,189,200,104,216,116,123,97,14,235,170,89,105,123,97,22,138,145,153,182,23,49,120,134,189,104,166,237,133,89,52,209,160,200,94,152,39,79,69,141,216,16,11,170,55,19,145,174,243,163,47,143,142,191,58,82,64,94,190,124,249,106,42,12,201,159,205,4,85,113,32,245,90,45,150,139,24,16,199,33,87,42,169,13,160,195,153,59,49,150,162,235,148,95,25,244,145,78,23,138,160,11,35,106,67,18,192,76,44,139,22,219,0,182,100,134,124,235,2,77,214,59,70,186,60,181,110,113,132,160,141,252,104,45,121,184,126,65,173,67,212,171,248,205,181,11,70,2,208,88,30,95,60,155,110,166,7,227,233,116,13,57,235,73,44,69,20,193,125,101,250,135,29,73,124,25,16,23,109,201,12,222,28,43,63,85,106,49,78,138,5,29,71,165,245,51,72,137,45,143,8,92,252,109,128,0,182,19,139,86,55,244,212,69,88,99,204,136,187,25,67,161,215,27,99,59,11,69,108,253,68,24,204,140,35,24,211,56,68,93,44,155,127,173,216,82,206,37,47,40,213,60,69,126,38,117,102,64,253,209,86,154,134,52,102,117,186,160,177,189,212,37,168,252,17,203,80,115,30,125,86,218,239,212,34,155,36,11,94,172,150,220,172,150,220,44,111,201,77,36,120,47,63,249,13,23,220,156,153,123,46,82,186,83,175,61,133,61,24,70,51,194,37,27,241,102,196,22,224,138,233,6,25,0,200,24,180,70,98,1,138,162,59,130,23,125,147,219,103,18,240,26,241,45,30,42,44,55,197,87,146,37,86,206,82,38,41,203,116,150,22,181,10,86,162,204,246,164,0,72,45,245,92,236,202,59,160,198,253,94,14,5,137,101,127,115,46,207,5,192,88,116,158,9,189,189,242,42,118,86,94,197,211,247,42,138,142,228,47,158,254,72,254,242,121,12,228,181,135,24,200,31,251,60,135,121,159,233,231,127,232,27,90,239,119,0,220,172,243,223,90,59,169,251,63,154,59,59,171,243,63,150,241,44,254,252,183,204,91,125,211,7,192,233,98,15,113,2,220,212,42,129,47,163,55,69,43,48,60,70,148,193,113,198,77,204,143,221,121,11,120,10,234,127,188,183,230,196,49,93,255,119,218,181,237,164,254,55,183,107,171,243,95,151,242,36,206,255,105,36,206,116,171,232,142,191,247,225,110,26,208,61,78,119,155,227,92,186,220,162,74,251,103,22,12,181,62,58,234,182,90,5,31,100,35,68,78,150,235,140,186,93,200,214,119,41,232,249,139,56,104,37,255,52,58,81,40,126,28,93,181,10,246,49,133,125,7,217,192,13,28,7,15,48,7,239,78,192,101,18,103,120,119,137,194,166,183,31,169,75,54,146,215,54,168,43,61,32,165,196,194,48,244,184,49,147,123,69,108,162,143,186,49,48,169,91,126,212,141,24,242,176,56,91,147,199,93,167,29,117,140,92,181,10,14,134,46,241,17,160,23,216,163,96,136,92,36,57,204,157,41,131,116,117,253,80,138,248,44,76,88,64,84,136,194,240,200,44,222,203,59,137,166,114,254,152,23,73,241,253,68,159,130,135,92,26,248,250,98,23,116,13,45,62,187,32,46,146,147,28,113,201,132,58,5,27,96,23,64,133,17,83,62,137,8,217,97,180,89,76,133,1,30,0,151,232,94,80,251,65,100,77,200,217,134,88,22,11,140,147,249,36,179,139,241,64,18,57,149,7,25,7,25,115,30,8,104,234,178,30,189,127,72,161,162,106,214,165,174,53,210,203,228,48,85,55,66,129,207,67,199,189,28,221,219,97,50,2,83,163,50,28,66,236,82,6,96,236,66,41,221,122,65,158,164,70,182,48,206,0,227,51,114,45,232,209,192,129,76,221,169,21,105,7,130,214,40,156,140,40,34,247,145,135,228,42,113,25,252,225,208,212,141,66,50,20,228,251,200,98,98,62,72,71,36,112,108,125,1,11,111,189,148,12,62,207,242,144,111,178,38,186,195,195,160,236,38,222,36,165,239,242,155,46,254,26,212,119,94,25,119,105,49,189,203,71,62,213,42,56,181,160,3,125,9,23,240,201,13,13,191,190,113,8,100,18,30,0,96,192,127,1,29,136,211,101,246,73,208,119,144,46,100,139,95,58,66,166,203,28,240,153,77,8,39,156,231,136,16,151,81,166,221,50,203,180,91,64,199,164,116,153,243,24,160,112,194,36,66,71,102,153,8,80,160,1,137,0,144,46,115,26,131,67,35,56,59,241,50,17,28,26,193,121,17,149,121,131,175,145,29,2,26,200,95,106,230,26,43,19,2,26,200,95,122,94,24,34,139,65,162,26,146,222,160,96,22,210,160,168,6,37,103,132,186,208,231,132,56,33,23,165,142,171,46,51,120,125,42,226,7,97,219,228,89,156,162,144,193,236,207,39,12,209,16,84,24,102,123,13,234,137,27,191,248,196,216,65,215,153,18,212,117,131,113,68,142,216,139,163,128,24,221,113,162,14,31,85,234,168,143,34,125,13,234,6,175,223,65,47,2,4,198,208,3,26,210,203,56,57,95,33,199,217,250,210,37,87,110,38,69,187,238,196,128,35,70,62,13,169,97,244,200,190,26,192,85,89,61,158,131,112,67,133,124,206,244,240,45,203,133,163,121,184,15,2,128,91,109,82,34,101,146,142,68,95,217,19,139,184,148,249,16,187,44,178,179,140,128,143,66,223,62,202,136,4,141,244,63,2,19,90,213,61,14,65,199,48,244,192,18,89,206,48,20,166,199,26,22,69,60,144,45,17,196,77,137,84,117,65,88,252,154,159,195,34,104,28,68,197,71,55,11,81,104,186,209,181,229,4,20,95,102,162,118,204,107,247,4,94,52,23,98,110,156,191,13,160,163,150,211,107,48,73,90,164,71,147,79,4,50,238,233,171,86,193,219,34,173,31,250,72,28,130,87,156,1,21,112,48,48,246,210,146,1,71,132,41,112,160,63,212,128,160,1,230,80,108,0,59,100,168,108,182,77,238,189,21,33,197,75,228,83,148,28,241,100,155,134,230,101,128,162,73,69,24,27,107,211,220,188,205,106,31,74,53,48,13,39,222,206,194,13,52,47,37,20,171,26,138,104,134,110,16,119,195,244,122,108,77,136,225,114,5,202,146,132,70,74,34,197,174,113,97,161,204,251,78,69,107,137,203,174,23,128,216,37,172,39,144,27,23,204,73,71,185,59,246,216,36,77,2,74,251,249,250,198,47,73,90,232,148,132,98,202,177,11,148,226,54,51,60,48,60,64,121,202,31,64,28,87,174,131,221,19,159,229,200,41,77,161,233,51,20,179,133,210,175,72,25,67,19,208,195,89,67,229,212,60,138,57,84,184,31,217,30,134,84,60,39,131,168,26,245,140,45,98,216,194,165,154,68,133,245,17,108,162,194,252,52,141,162,49,39,41,102,19,197,180,37,101,18,13,48,15,103,17,195,115,68,151,111,16,37,234,71,182,135,154,136,231,100,14,101,155,158,177,53,212,13,92,170,49,212,71,27,47,221,22,74,196,79,214,20,234,48,71,97,83,216,110,101,153,66,13,230,65,77,97,187,245,104,166,176,221,250,4,76,161,32,226,153,153,194,118,235,153,155,66,209,192,101,155,194,118,235,145,76,97,187,245,68,77,225,249,220,110,97,144,237,23,158,47,197,49,12,30,209,51,12,62,9,215,48,120,142,190,97,240,236,157,195,224,81,188,195,224,209,220,195,224,41,251,135,231,115,59,136,65,182,135,120,190,20,23,49,120,68,31,49,248,36,156,196,224,57,122,137,193,179,119,19,131,71,241,19,131,71,115,20,131,167,236,41,158,206,237,41,210,108,79,241,116,41,158,34,125,68,79,145,126,18,158,34,125,142,158,34,125,246,158,34,125,20,79,145,62,154,167,72,159,178,167,120,58,183,167,72,179,61,197,211,165,120,138,244,17,61,69,250,73,120,138,244,57,122,138,244,217,123,138,244,81,60,69,250,104,158,34,125,202,158,98,108,177,105,193,181,136,178,74,122,53,162,9,234,1,215,35,170,5,177,143,179,34,81,33,127,236,53,137,33,25,207,201,52,234,86,61,99,219,24,53,113,185,43,19,21,218,199,88,155,168,80,63,97,243,56,159,211,168,214,226,103,155,199,135,119,27,245,86,128,199,51,143,143,239,56,70,100,60,59,243,248,188,93,199,168,137,203,55,143,143,227,60,106,212,79,211,60,158,222,193,125,164,121,254,227,233,146,28,72,250,168,30,36,253,68,92,72,250,60,125,72,250,59,224,68,210,71,242,34,233,35,186,145,244,105,251,145,167,119,112,36,105,158,39,121,186,36,87,146,62,170,47,73,63,17,103,146,62,79,111,146,254,14,184,147,244,145,252,73,250,136,14,37,125,218,30,101,180,103,189,152,145,228,192,82,6,50,2,242,112,198,81,180,194,48,140,202,206,27,187,233,117,3,166,27,121,81,33,109,226,13,56,15,104,224,229,110,255,44,243,142,138,40,72,28,129,27,140,251,200,7,100,160,129,88,35,232,67,139,33,159,130,141,115,23,139,211,67,197,63,30,225,124,216,172,136,51,145,35,241,155,6,96,12,39,192,198,131,1,242,193,192,39,227,120,121,117,34,129,58,232,68,182,42,123,249,138,131,92,243,152,128,106,21,188,195,238,82,26,11,32,3,16,140,177,139,199,193,248,17,90,62,198,110,79,182,222,24,74,223,193,235,101,54,30,94,63,86,227,225,181,106,124,51,38,227,226,92,139,187,55,95,18,160,225,153,29,156,39,124,61,73,178,60,95,194,16,193,229,18,194,101,65,19,210,138,73,195,3,208,33,59,61,183,91,52,29,198,224,252,30,50,134,124,45,150,121,84,140,33,179,70,225,201,62,153,227,163,143,134,129,3,125,128,174,195,227,66,55,78,186,13,32,15,32,219,172,168,195,111,197,61,250,182,89,74,141,116,200,145,23,252,201,214,184,19,96,35,117,63,43,77,122,26,210,146,122,138,242,248,168,255,222,71,3,124,61,139,171,226,118,217,56,95,105,208,87,128,33,211,192,120,137,62,26,98,215,21,231,10,13,242,101,95,211,36,177,131,184,39,112,26,12,22,75,19,114,237,34,212,80,137,55,58,149,86,143,108,140,247,227,125,232,49,250,233,106,132,124,52,213,46,68,35,159,196,171,15,152,213,94,90,1,130,148,175,182,104,146,184,219,102,144,213,104,46,205,105,149,248,177,60,112,61,60,171,118,105,126,107,212,124,225,181,214,13,111,228,43,228,56,242,20,31,233,150,122,62,185,20,247,100,218,151,208,181,144,29,247,174,148,69,176,200,120,204,85,57,214,19,74,65,37,110,121,10,214,21,114,156,222,133,128,30,59,11,171,59,134,216,201,242,146,227,252,134,210,107,6,72,20,135,182,205,109,8,128,212,4,37,46,42,151,167,13,159,188,217,3,219,205,70,35,252,44,252,72,89,57,60,210,215,172,251,5,161,76,28,115,90,152,146,145,174,49,149,136,122,173,217,226,6,16,83,131,123,209,93,215,234,124,62,19,128,56,241,221,133,82,92,241,119,98,143,253,24,98,87,156,194,74,193,198,193,254,17,221,172,196,27,22,210,34,15,157,50,193,29,120,197,155,116,240,30,108,92,182,248,220,239,178,189,169,153,92,49,161,125,80,229,46,219,250,51,31,199,164,25,231,237,81,86,30,208,192,247,73,160,174,9,255,54,128,62,2,125,31,90,23,136,209,4,233,88,157,42,165,142,194,138,147,126,217,154,135,248,203,86,154,102,133,227,178,165,113,108,167,112,180,231,194,17,54,188,34,153,17,3,182,80,190,92,182,53,205,237,56,205,231,62,46,76,114,25,192,62,37,78,192,16,56,63,57,0,144,106,1,53,1,42,89,109,190,124,209,142,19,17,248,56,236,156,157,20,17,39,104,80,156,117,113,236,10,165,9,144,99,23,7,185,115,103,180,143,228,197,133,248,18,113,113,212,109,168,164,200,235,249,104,0,212,185,101,38,180,93,101,33,102,210,135,176,184,65,97,126,173,6,27,87,35,108,141,82,186,156,171,192,38,60,169,203,196,7,66,155,203,252,47,113,153,140,155,171,142,137,166,107,11,168,14,71,139,245,76,128,237,57,250,229,252,96,63,222,49,38,44,222,216,86,61,105,71,131,64,93,159,33,143,92,51,43,132,99,200,9,26,34,211,241,129,122,164,224,3,1,144,3,129,246,227,52,110,200,139,249,188,98,212,90,3,88,52,132,244,68,161,232,194,248,168,219,29,111,4,251,136,77,233,120,206,100,17,71,81,195,63,128,186,78,5,160,202,176,2,224,110,130,213,33,76,217,226,157,12,148,110,48,158,130,82,25,2,141,176,79,216,40,132,186,193,167,109,174,118,238,55,248,116,93,81,81,207,32,67,224,145,100,36,4,254,144,92,33,223,130,116,202,8,150,106,185,19,214,49,168,209,248,97,28,125,84,86,162,79,28,1,200,40,178,40,243,231,64,78,145,21,248,161,71,66,227,216,52,56,121,100,101,77,31,235,167,253,11,49,158,202,248,14,149,87,23,14,209,53,162,224,139,179,179,247,189,47,186,187,251,221,147,222,209,238,187,174,224,172,249,242,195,238,225,121,87,30,251,9,251,78,20,66,101,62,182,194,91,12,147,135,229,86,171,230,57,168,210,33,195,20,48,63,64,229,16,67,186,50,21,167,192,158,188,217,219,178,200,216,115,48,116,89,8,239,20,49,113,121,56,35,96,0,29,138,228,125,84,146,40,0,129,67,8,77,192,18,236,36,242,198,89,10,29,135,92,133,19,192,63,244,255,208,253,195,154,49,159,47,3,105,154,148,61,209,71,157,246,39,30,164,84,19,42,38,118,226,234,126,238,236,101,157,84,171,184,242,26,52,182,193,215,250,66,138,215,162,221,223,60,129,96,103,163,173,195,133,9,163,20,74,32,25,35,97,84,182,98,230,136,86,74,226,212,76,163,134,244,88,213,213,155,224,53,48,124,118,179,239,213,192,145,28,45,118,26,205,154,228,111,74,62,99,209,192,132,24,5,197,97,73,177,22,49,39,21,223,141,78,18,45,20,31,21,225,129,116,128,55,130,242,128,17,94,17,153,88,116,112,212,8,145,228,4,39,155,139,11,78,222,33,46,180,240,24,225,29,98,66,169,80,221,179,136,8,181,22,16,17,146,50,41,45,152,6,86,44,26,164,14,237,53,162,65,219,11,136,6,101,209,51,43,18,164,40,49,34,65,237,133,68,130,226,114,86,36,228,162,40,49,194,45,59,203,138,182,132,161,107,144,140,133,45,33,214,34,145,135,161,150,151,139,137,180,112,168,119,136,179,220,59,14,0,226,51,24,78,134,186,142,54,99,66,111,196,181,192,125,39,243,188,251,194,70,43,104,217,136,47,91,102,68,11,220,119,134,63,7,226,182,113,38,248,237,167,239,26,213,91,218,81,136,78,11,47,226,39,8,191,40,225,36,68,16,150,115,248,161,122,98,174,194,190,116,146,142,57,91,102,163,21,220,51,148,217,140,136,132,170,28,93,103,193,27,93,22,55,62,168,43,6,248,128,20,184,218,49,19,197,179,220,103,13,183,39,240,197,6,251,37,29,128,23,61,177,97,126,217,71,225,105,18,66,161,139,93,155,80,72,238,198,125,100,115,87,65,11,157,196,89,17,123,7,136,175,95,111,137,171,22,68,35,104,25,228,221,82,225,243,137,39,197,151,200,153,68,119,60,196,72,10,5,249,244,2,103,154,205,98,154,43,153,152,210,222,172,153,214,133,10,131,198,164,58,188,189,100,182,172,80,196,50,192,26,87,141,132,51,131,248,201,255,133,38,7,186,87,83,243,131,56,172,27,195,157,62,96,40,43,32,50,211,185,72,37,169,177,0,84,200,165,150,69,99,28,124,7,175,31,132,146,25,142,181,166,196,208,248,115,121,95,109,130,14,200,39,253,14,18,87,220,75,23,42,213,179,242,162,91,153,66,208,192,184,39,37,19,9,152,74,107,166,238,174,239,59,72,92,105,41,239,23,129,174,45,45,54,87,11,10,54,84,183,201,184,132,75,194,188,162,10,92,34,123,51,211,140,233,187,118,147,102,36,205,89,20,81,166,111,150,49,149,24,90,35,193,69,237,44,138,134,86,34,105,87,182,35,113,187,145,136,140,80,38,226,35,215,200,10,88,76,253,180,115,20,2,215,224,2,87,44,77,20,154,133,169,209,177,220,93,205,191,153,70,119,93,235,9,4,56,182,67,123,170,47,234,40,164,206,99,232,165,52,57,132,96,42,241,123,136,253,133,168,206,151,31,10,170,176,39,48,38,85,248,1,232,152,161,192,154,142,134,57,104,158,122,208,143,133,87,149,163,16,215,219,104,240,12,92,138,152,202,253,241,174,14,231,76,81,220,114,12,189,159,80,121,105,87,108,100,147,26,155,165,141,46,233,81,73,71,76,23,191,68,147,12,85,164,211,117,241,2,77,50,84,49,75,43,46,56,248,196,228,250,131,108,253,28,72,99,43,81,53,5,161,121,53,9,209,195,177,102,177,97,3,116,63,227,120,120,52,62,186,222,93,255,21,194,248,42,214,79,213,0,132,1,206,240,134,157,208,0,100,41,127,184,244,153,187,220,114,9,113,181,10,62,38,175,17,219,117,39,31,205,176,168,184,244,93,139,103,136,41,125,199,218,2,188,148,122,49,23,249,39,20,124,228,84,245,2,223,249,56,205,95,14,71,184,248,228,66,105,86,238,154,140,70,97,95,57,131,146,164,235,204,103,11,145,9,202,152,234,228,80,19,198,13,154,225,29,30,177,11,146,102,218,250,130,221,173,161,230,247,121,28,239,67,119,252,194,39,143,121,13,14,99,206,141,101,238,183,200,165,70,228,86,154,15,66,74,206,150,139,41,164,160,228,102,133,7,217,130,81,144,28,177,117,98,251,94,91,39,22,201,29,185,203,161,189,172,217,124,46,29,201,93,7,75,152,214,231,210,18,26,171,112,135,65,226,154,182,69,89,171,16,108,190,185,74,96,126,242,246,42,108,207,167,97,176,34,114,210,22,107,190,29,99,11,80,74,147,152,79,193,102,69,244,124,26,70,203,164,39,97,181,14,217,17,185,202,36,41,187,167,172,192,247,145,203,196,133,139,21,89,59,140,71,232,181,29,122,177,129,152,209,240,74,95,97,54,194,210,47,206,154,205,56,172,231,146,171,196,154,233,183,51,9,75,113,41,78,219,219,133,208,54,12,105,51,178,70,170,206,236,142,188,146,5,197,151,240,38,203,184,83,26,39,58,185,68,212,92,187,1,29,97,168,253,136,118,217,121,208,181,227,76,203,90,202,145,107,179,21,137,34,49,117,251,216,151,149,175,158,133,63,226,162,245,9,28,59,15,136,99,250,253,255,181,86,115,187,37,239,255,231,255,223,222,254,65,173,222,216,169,183,87,247,255,47,227,217,218,218,42,201,149,167,29,16,221,229,95,98,158,211,27,96,7,245,208,53,235,128,245,10,243,156,245,82,9,219,78,167,4,128,182,18,29,97,67,100,188,21,246,29,212,145,95,44,241,250,18,249,20,19,183,55,230,144,47,155,149,118,165,22,123,111,141,237,14,88,95,23,239,160,207,240,0,90,140,79,144,59,96,125,196,152,71,59,213,234,16,179,81,208,175,88,100,92,229,164,109,9,210,212,159,100,203,26,219,14,118,81,213,71,14,130,20,209,170,77,174,92,135,64,187,122,89,171,212,42,245,173,31,223,16,122,43,111,244,183,36,158,177,189,29,226,244,145,71,40,102,196,159,132,175,6,208,113,250,208,186,232,128,117,79,192,4,216,165,12,58,142,106,23,24,96,159,178,50,160,8,117,64,6,145,178,20,113,250,193,96,128,124,90,213,124,226,208,7,14,100,234,125,154,109,252,99,6,215,20,89,203,230,152,160,230,158,12,19,48,178,249,37,71,26,69,41,38,85,131,51,230,223,189,97,128,109,212,235,7,216,177,177,59,172,140,216,152,139,32,35,196,17,28,28,18,201,199,173,12,1,220,26,34,119,107,72,84,2,62,139,167,217,92,93,134,36,42,218,52,66,147,195,9,30,27,72,135,196,129,238,48,20,168,108,80,70,111,172,103,176,102,72,240,216,35,62,163,159,24,91,66,186,138,176,68,240,161,66,252,97,245,186,42,68,161,106,141,237,52,136,25,172,24,19,235,98,136,220,79,140,17,138,170,59,73,6,175,171,1,252,193,101,157,91,219,76,94,148,60,39,24,98,55,161,65,244,10,14,135,200,87,191,136,135,92,232,97,245,75,5,174,145,250,25,151,34,254,123,48,102,234,111,147,173,252,11,131,195,18,0,150,231,105,60,150,231,245,198,228,18,149,74,12,141,61,7,50,68,211,227,137,38,11,0,72,41,98,61,27,251,157,176,72,85,190,11,117,155,55,222,24,168,194,247,20,121,208,135,140,248,124,240,210,156,184,64,200,235,17,31,15,123,46,28,163,142,88,163,172,217,235,89,61,138,252,75,228,247,40,11,250,29,192,127,96,11,245,196,144,72,248,248,151,46,201,16,101,233,226,226,117,186,142,229,96,228,170,226,234,53,103,137,239,89,85,150,64,18,114,108,26,11,44,207,155,222,172,212,136,147,201,88,211,250,62,119,222,62,182,175,245,41,62,124,126,71,2,214,195,182,83,29,146,234,8,123,30,169,14,73,101,76,108,206,179,133,224,152,225,255,115,183,159,251,255,181,102,163,181,211,172,239,252,160,86,223,169,181,182,87,254,255,50,158,155,155,45,240,99,239,98,120,4,199,8,116,94,131,202,123,104,93,192,33,18,191,183,110,111,75,162,0,189,244,117,129,13,236,218,232,26,84,78,165,86,82,80,219,172,132,133,101,233,33,121,127,49,60,22,161,5,94,99,125,61,4,36,66,19,149,55,216,65,242,51,173,12,73,207,147,24,69,33,0,82,16,94,131,74,88,31,185,118,132,7,15,0,250,22,84,222,146,119,196,214,72,198,196,14,28,36,103,50,208,243,42,55,55,154,118,13,193,161,200,44,121,115,35,1,24,8,56,252,33,145,95,62,72,47,224,246,246,185,26,143,76,253,231,211,65,101,52,23,129,99,134,254,215,183,91,219,73,253,111,212,119,86,250,191,140,167,116,115,3,126,44,3,0,161,9,216,151,91,201,133,74,128,31,11,95,54,252,246,54,252,165,62,43,63,89,237,90,224,69,62,196,222,132,86,97,166,145,121,120,179,161,171,136,141,182,37,233,200,130,141,210,90,15,172,223,220,24,92,184,189,173,222,220,68,13,191,189,149,174,252,0,59,12,249,85,27,245,131,161,67,134,55,55,241,198,223,222,174,207,11,202,71,22,185,68,254,36,15,212,144,84,130,62,242,197,132,7,6,140,140,225,181,231,19,139,174,151,74,107,133,240,12,73,26,116,213,33,67,14,128,23,40,70,109,22,20,233,248,21,170,110,67,6,251,144,34,105,93,178,64,109,150,74,131,192,181,68,199,108,108,130,155,210,26,229,34,32,204,248,17,186,58,21,62,225,198,166,140,176,11,40,149,19,52,196,148,33,255,11,232,218,14,242,213,112,180,65,203,96,36,222,108,150,74,107,124,132,240,125,14,137,138,241,10,109,108,190,18,111,126,248,26,184,216,225,120,214,28,50,172,188,129,12,58,27,200,247,55,75,107,183,165,91,69,140,132,179,97,49,185,25,16,93,179,202,158,252,111,57,92,136,245,153,36,70,173,68,218,228,192,137,207,225,250,136,5,190,203,177,148,62,233,177,35,211,254,115,190,247,134,100,81,113,225,25,246,127,167,214,72,217,255,86,123,21,255,93,202,83,208,255,67,151,62,182,80,33,31,208,172,240,94,69,68,37,100,253,35,44,5,189,104,96,217,85,127,27,32,184,210,135,223,79,163,159,188,200,208,33,125,232,116,0,248,17,120,43,254,228,58,58,192,67,149,183,170,148,128,60,62,193,131,22,234,128,125,116,137,28,226,141,145,203,120,141,174,123,137,125,226,138,159,108,226,161,178,62,224,225,189,79,236,192,146,105,56,223,172,197,225,33,247,82,79,110,17,77,193,17,219,122,7,196,7,46,113,183,188,8,14,138,202,208,74,169,36,91,37,232,150,45,74,211,13,61,175,3,110,110,240,32,100,208,237,237,205,141,249,55,119,98,111,111,39,36,240,21,215,110,110,144,107,223,222,114,168,187,114,145,183,92,112,161,105,18,7,85,5,20,187,234,216,19,77,197,205,13,247,162,77,86,203,209,84,141,167,169,247,49,15,218,40,22,73,135,81,78,83,244,222,39,150,88,101,41,219,203,137,226,52,244,197,82,94,54,234,128,106,64,253,170,67,44,232,8,203,83,237,99,183,42,42,66,54,18,11,68,177,11,253,137,17,193,3,3,236,32,42,150,174,15,124,56,70,87,196,191,136,243,81,150,224,104,248,235,28,60,252,83,28,145,98,81,30,44,62,144,229,192,226,159,178,97,241,47,17,8,57,240,139,254,63,196,148,1,50,144,71,129,88,200,99,196,151,27,138,160,227,232,160,135,26,132,124,192,71,36,233,250,232,152,29,30,123,14,210,190,136,122,169,253,9,14,254,64,131,5,30,116,177,69,229,161,125,33,89,158,236,21,236,14,193,144,248,36,96,252,53,176,124,189,43,81,174,55,213,220,213,66,131,185,54,41,217,21,154,175,54,37,134,53,52,252,178,200,77,139,117,184,227,192,97,216,211,249,243,155,27,121,82,236,143,133,13,41,75,33,227,45,213,74,206,193,38,133,208,176,61,250,119,37,38,174,91,64,106,166,80,27,46,23,161,109,201,18,110,254,8,223,194,84,43,49,87,12,203,70,191,227,146,173,201,138,105,65,72,171,50,164,51,43,139,89,38,231,227,9,9,24,138,235,169,110,159,42,143,189,14,168,55,118,42,34,82,108,176,30,56,220,253,17,91,141,15,222,235,205,136,146,235,1,69,192,115,160,133,70,196,177,145,15,126,124,131,189,219,10,56,167,225,65,54,216,227,246,205,197,86,153,255,201,224,133,232,73,76,124,204,38,26,241,143,248,247,14,64,108,84,83,111,184,187,204,89,12,109,27,188,168,213,106,170,15,101,75,210,100,241,226,121,4,241,111,183,26,147,139,24,151,177,14,96,150,199,65,29,201,223,6,40,110,164,229,103,226,131,192,246,116,77,157,113,227,84,37,199,156,180,57,116,224,4,249,70,29,225,0,19,95,164,166,52,68,134,199,136,4,172,3,234,188,129,224,71,224,157,220,5,96,234,11,47,35,186,203,71,223,6,136,202,93,57,99,236,56,152,34,139,184,54,213,146,30,134,19,100,128,82,104,206,231,208,186,224,175,19,38,134,248,64,22,2,22,116,28,1,97,46,82,184,205,232,75,208,180,248,224,151,85,179,168,133,82,117,66,203,20,17,158,105,158,76,235,177,151,106,59,118,109,124,137,237,0,198,105,89,153,139,184,185,208,74,22,31,216,37,195,66,109,42,220,243,89,149,115,84,81,238,153,140,215,49,21,18,108,196,229,57,110,82,54,31,80,95,161,63,68,172,195,205,100,181,26,218,201,206,12,35,165,247,110,155,74,156,99,1,10,154,128,148,202,235,68,155,240,9,196,223,105,79,207,33,67,169,103,100,152,254,8,244,97,66,162,200,190,58,89,199,73,22,45,235,157,121,52,28,104,1,9,152,23,68,45,218,2,87,62,22,58,109,17,151,18,7,41,29,20,127,82,6,93,27,250,182,170,4,54,20,86,227,44,49,135,139,81,7,8,101,214,228,138,119,130,3,9,0,105,164,220,247,145,213,44,113,173,144,131,120,43,82,224,177,59,32,105,232,78,84,201,39,142,216,92,237,144,161,113,14,158,196,210,147,60,137,178,63,194,142,33,169,229,21,153,5,226,172,51,28,52,202,136,143,102,195,7,98,175,23,197,223,33,46,17,166,56,240,119,220,58,230,128,224,131,194,187,207,147,128,184,238,4,30,77,194,138,78,104,225,84,134,222,162,89,19,14,81,7,236,100,87,178,225,68,108,165,186,64,200,75,209,111,145,177,56,58,165,163,78,145,2,63,2,95,141,144,240,3,24,9,191,154,136,31,123,82,186,122,150,246,36,227,63,140,121,139,78,255,221,33,255,215,222,169,173,242,127,75,121,86,249,191,85,254,47,169,255,11,78,255,205,206,255,181,219,169,252,127,187,177,210,255,101,60,171,252,223,42,255,119,199,252,223,26,227,214,226,238,16,132,177,153,51,247,39,80,86,100,206,239,77,224,90,27,235,213,245,40,227,23,149,208,217,65,53,109,10,179,131,11,203,10,94,1,133,135,122,196,165,232,43,49,11,41,3,31,124,166,222,139,105,225,167,159,16,204,178,255,11,78,255,221,37,255,215,108,172,242,127,75,121,86,249,191,85,254,111,149,255,91,229,255,86,249,191,85,254,111,149,255,91,229,255,86,249,191,79,217,92,172,242,127,171,252,223,42,255,183,202,255,173,242,127,171,103,49,79,34,254,115,1,7,23,240,83,216,255,87,107,174,226,63,203,120,86,249,191,85,254,47,165,255,75,222,255,215,174,167,226,191,245,237,149,254,47,229,89,229,255,86,249,191,165,237,255,19,214,229,222,251,255,4,148,71,222,255,119,129,38,101,117,76,249,215,223,244,39,12,149,1,35,30,182,212,185,204,101,224,65,159,97,117,2,43,107,54,202,128,12,6,20,137,123,95,219,173,79,40,45,152,105,255,63,129,253,127,141,214,202,254,47,227,89,229,255,86,249,191,85,254,111,149,255,91,229,255,86,249,191,85,254,111,149,255,91,229,255,62,101,115,177,202,255,173,242,127,171,252,223,42,255,183,202,255,173,158,197,60,137,248,15,183,107,254,167,144,255,107,173,214,127,47,229,89,229,255,86,249,191,148,254,47,253,252,207,157,212,249,159,141,213,254,191,165,60,171,244,223,42,253,183,172,244,159,48,46,247,78,255,9,40,143,154,254,139,210,119,114,78,139,93,230,184,27,235,35,228,56,68,16,253,195,245,205,199,207,236,21,123,50,237,255,146,243,127,245,118,35,149,255,219,169,175,236,255,50,158,85,254,111,149,255,91,229,255,86,249,191,85,254,111,149,255,123,244,252,223,250,103,213,58,248,44,252,223,255,193,135,102,182,203,142,93,11,189,174,175,115,44,103,220,63,1,150,207,13,235,181,136,91,98,226,118,192,215,50,241,6,198,216,229,252,28,145,192,7,54,156,128,49,113,217,8,92,33,116,97,195,201,55,128,6,214,8,64,10,214,107,224,179,234,182,198,179,14,144,208,153,109,85,157,174,146,139,171,228,226,239,160,45,90,37,23,87,201,197,85,114,113,149,92,92,37,23,87,207,234,89,61,171,231,119,224,249,95,1,0,0,255,255,9,71,53,228,0,204,13,0, +} \ No newline at end of file diff --git a/install/VERSION b/install/VERSION new file mode 100644 index 0000000..95e94cd --- /dev/null +++ b/install/VERSION @@ -0,0 +1 @@ +v0.0.1 \ No newline at end of file diff --git a/install/flatbuffers/asset_go/cmd/client/main.go.tpl b/install/flatbuffers/asset_go/cmd/client/main.go.tpl new file mode 100644 index 0000000..3ddfefb --- /dev/null +++ b/install/flatbuffers/asset_go/cmd/client/main.go.tpl @@ -0,0 +1,184 @@ +package main + +{{ $domainName := .Domain }} +{{- $sevriceProtocol := .Protocol -}} +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgName = . -}} +{{- end -}} +import ( + trpc "{{$domainName}}/trpc-go/trpc-go" + "{{$domainName}}/trpc-go/trpc-go/client" + "{{$domainName}}/trpc-go/trpc-go/log" + fb "{{$goPkgName}}" + flatbuffers "github.com/google/flatbuffers/go" + {{ range $.Imports }} + {{/* Specify the importName explicitly, for example: import "{{ $domainName }}/..../structpb;xxx" */}} + {{ if contains . ";" }} + {{ $val := (splitList ";" .) }} + {{ index $val 1}} "{{index $val 0}}" + {{ else }} + "{{- . -}}" + {{ end }} + {{ end }} +) +{{- range $index, $service := .Services -}} +{{- $svrNameCamelCase := $service.Name | camelcase -}} +{{- range $mindex, $method := $service.RPC -}} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "fb.%s" (splitList "." $rpcReqType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltype $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "fb.%s" (splitList "." $rpcRspType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltype $rpcRspType $.FileDescriptor) -}} +{{- end }} + +func call{{$svrNameCamelCase}}{{$rpcName}}() { + proxy := fb.New{{$svrNameCamelCase}}ClientProxy( + client.WithTarget("ip://127.0.0.1:{{add 8000 $index}}"), + client.WithProtocol("{{$sevriceProtocol}}"), + ) + ctx := trpc.BackgroundContext() +{{- if and $method.ClientStreaming $method.ServerStreaming}} + // Example of using a bidirectional streaming client. + stream, err := proxy.{{$rpcName}}(ctx) + if err != nil { + log.Fatalf("err: %v", err) + } + for i := 0; i < 5; i++ { + b := flatbuffers.NewBuilder(clientFBBuilderInitialSize) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("{{$svrNameCamelCase}}{{$rpcName}} %v", i)) + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, idx) + b.Finish({{$rpcReqType}}End(b)) + if err := stream.Send(b); err != nil { + log.Fatalf("err: %v", err) + } + } + if err := stream.CloseSend(); err != nil { + log.Fatalf("err: %v", err) + } + for { + rsp, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("err: %v", err) + } + // Replace "Message" with the field name you need to access. + // log.Debugf(" bidi stream receive: %q", rsp.Message()) + log.Debugf(" bidi stream receive: %v", rsp) + } +{{- else if $method.ClientStreaming}} + // Example usage of client-side streaming. + stream, err := proxy.{{$rpcName}}(ctx) + if err != nil { + log.Fatalf("err: %v", err) + } + for i := 0; i < 5; i++ { + b := flatbuffers.NewBuilder(clientFBBuilderInitialSize) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("{{$svrNameCamelCase}}{{$rpcName}} %v", i)) + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, idx) + b.Finish({{$rpcReqType}}End(b)) + if err := stream.Send(b); err != nil { + log.Fatalf("err: %v", err) + } + } + rsp, err := stream.CloseAndRecv() + if err != nil { + log.Fatalf("err: %v", err) + } + // Replace "Message" with the field name you need to access. + // log.Debugf("client stream receive: %q", rsp.Message()) + log.Debugf("client stream receive: %v", rsp) +{{- else if $method.ServerStreaming}} + // Example usage of server-side streaming. + b := flatbuffers.NewBuilder(clientFBBuilderInitialSize) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // i := b.CreateString("{{$svrNameCamelCase}}{{$rpcName}}") + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, i) + b.Finish({{$rpcReqType}}End(b)) + stream, err := proxy.{{$rpcName}}(ctx, b) + if err != nil { + log.Fatalf("err: %v", err) + } + for { + reply, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("err: %v", err) + } + // Replace "Message" with the field name you need to access. + // log.Debugf("server stream receive: %q", reply.Message()) + log.Debugf("server stream receive: %v", reply) + } +{{- else}} + // Example usage of unary client. + b := flatbuffers.NewBuilder(clientFBBuilderInitialSize) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // i := b.CreateString("{{$svrNameCamelCase}}{{$rpcName}}") + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, i) + b.Finish({{$rpcReqType}}End(b)) + reply, err := proxy.{{$rpcName}}(ctx, b) + if err != nil { + log.Fatalf("err: %v", err) + } + // Replace "Message" with the field name you need to access. + // log.Debugf("simple rpc receive: %q", reply.Message()) + log.Debugf("simple rpc receive: %v", reply) +{{- end}} +} +{{- end}} +{{- end}} + +// clientFBBuilderInitialSize sets the initial size for initializing flatbuffers.NewBuilder on the client side. +var clientFBBuilderInitialSize int + +func init() { + flag.IntVar(&clientFBBuilderInitialSize, "n", 1024, "set client flatbuffers builder's initial size") +} + +func main() { + flag.Parse() +{{- range $index, $service := .Services -}} +{{- $svrNameCamelCase := $service.Name | camelcase -}} +{{- range $mindex, $method := $service.RPC -}} +{{- $rpcName := $method.Name | camelcase }} + call{{$svrNameCamelCase}}{{$rpcName}}() +{{- end}} +{{- end}} +} \ No newline at end of file diff --git a/install/flatbuffers/asset_go/go.mod.tpl b/install/flatbuffers/asset_go/go.mod.tpl new file mode 100755 index 0000000..4d1ebfe --- /dev/null +++ b/install/flatbuffers/asset_go/go.mod.tpl @@ -0,0 +1,49 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{ $domainName := .Domain }} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} + + + +{{ $rpcdir := "" -}} +{{ if ne $goPkgOption "" -}} +{{ $rpcdir = trimright ";" $goPkgOption }} +{{- else -}} +{{ $rpcdir = $pkgName }} +{{- end -}} +replace {{$rpcdir}} => ./stub/{{$rpcdir}} + +{{ range $k, $v := .Pb2ImportPath -}} +{{ $v = trimright ";" $v}} +{{ if and (not (hasprefix "trpc.tech/trpc-go/trpc/v2" $v)) + (not (hasprefix "trpc.group/trpc-go/trpc" $v)) + (not (hasprefix "trpc.group/trpc/trpc-protocol" $v)) + (not (hasprefix "trpc.group/wineguo/trpc-protocol" $v)) + (not (hasprefix "github.com/golang/protobuf" $v)) + (ne $v "trpc.group/devsec/protoc-gen-secv/v2/validate") + (ne $v "trpc.group/devsec/protoc-gen-secv/validate") + (not (hasprefix "google/protobuf/" $k)) }} +replace {{$v}} => ./stub/{{$v}} +{{ end }} + +{{ end }} + + +{{ if ne $.TRPCGoVersion "" }} +require trpc.group/trpc-go/trpc-go {{.TRPCGoVersion}} +{{ end }} + +require github.com/google/flatbuffers v2.0.0+incompatible diff --git a/install/flatbuffers/asset_go/main.go.tpl b/install/flatbuffers/asset_go/main.go.tpl new file mode 100755 index 0000000..9b48352 --- /dev/null +++ b/install/flatbuffers/asset_go/main.go.tpl @@ -0,0 +1,50 @@ +{{ $domainName := .Domain }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +{{- $serviceSuffix := "" -}} +{{- if not .NoServiceSuffix }} + {{- $serviceSuffix = "Service" }} +{{- end }} +package main + +import ( + {{if secvtpl $.Pkg2ValidGoPkg -}} + {{/* _ "{{$domainName}}/trpc-go/trpc-filter/validation" */}} + {{ end -}} + _ "{{ $domainName }}/trpc-go/trpc-filter/debuglog" + _ "{{ $domainName }}/trpc-go/trpc-filter/recovery" + trpc "{{ $domainName }}/trpc-go/trpc-go" + "{{ $domainName }}/trpc-go/trpc-go/log" + + {{ if ne $goPkgOption "" -}} + fb "{{$goPkgOption}}" + {{- else -}} + fb "{{$pkgName}}" + {{- end }} +) + +{{- $appName := .AppName -}} +{{- $serverName := .ServerName }} + +func main() { + flag.Parse() + s := trpc.NewServer() + // If there are multiple services, it is necessary to explicitly write the service name as the first parameter; + // otherwise, there may be issues with streaming. + {{range $index, $service := .Services}} + {{- $svrNameCamelCase := $service.Name | camelcase -}} + {{- $serviceName := $service.Name -}} + fb.Register{{$svrNameCamelCase}}{{$serviceSuffix}}(s.Service("{{- if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end -}}"), &{{$svrNameCamelCase|untitle}}Impl{}) + {{end -}} + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} diff --git a/install/flatbuffers/asset_go/rpc/go.mod.tpl b/install/flatbuffers/asset_go/rpc/go.mod.tpl new file mode 100755 index 0000000..5e42369 --- /dev/null +++ b/install/flatbuffers/asset_go/rpc/go.mod.tpl @@ -0,0 +1,23 @@ +{{- /* $pkgName .PackageName example: trpc.testapp.testserver */}} +{{- $pkgName := .PackageName -}} +{{- /* $goPkgOption example: "trpc.group/trpcprotocol/testapp/testserver/greeter" */}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if ne $goPkgOption "" -}} +module {{$goPkgOption}} +{{- else -}} +module {{$pkgName}} +{{- end }} + +go {{.GoVersion}} + + + +{{ if ne $.TRPCGoVersion "" }} +require trpc.group/trpc-go/trpc-go {{.TRPCGoVersion}} +{{ end }} + +require github.com/google/flatbuffers v2.0.0+incompatible diff --git a/install/flatbuffers/asset_go/rpc/trpc.go.tpl b/install/flatbuffers/asset_go/rpc/trpc.go.tpl new file mode 100755 index 0000000..017b5a3 --- /dev/null +++ b/install/flatbuffers/asset_go/rpc/trpc.go.tpl @@ -0,0 +1,584 @@ +// Code generated by trpc-go/trpc-cmdline {{ .TRPCCmdlineVersion }}. DO NOT EDIT. +// source: {{.Protofile}} + +{{- /* .Protofile example: file1.fbs */}} +{{- /* $domainName .Domain example: trpc.group */}} + +{{ $domainName := .Domain }} +{{- $serviceSuffix := "" -}} +{{- if not .NoServiceSuffix }} + {{- $serviceSuffix = "Service" }} +{{- end }} + +{{- /* $pkgName .PackageName example: trpc.testapp.testserver */}} +{{- /* $goPkgName example: trpc_testapp_testserver */}} +{{- /* $appName example: testapp */}} +{{- /* $serverName example: testserver */}} +{{- /* $protocol example: "trpc" */}} +{{- /* $fbsfile example: "file1.fbs" */}} +{{- /* $goPkgOption example: "trpc.group/trpcprotocol/testapp/testserver/greeter" */}} +{{- /* $goPkgName example: "greeter" */}} + +{{ $pkgName := .PackageName -}} +{{ $goPkgName := .PackageName|gopkg -}} +{{ $appName := .AppName -}} +{{ $serverName := .ServerName -}} +{{ $protocol := .Protocol -}} +{{ $fbsfile := .Protofile -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} + {{- $goPkgName = (splitList "/" $goPkgOption)|last|gopkg -}} +{{- end -}} +{{- $importStream := false }} +{{- $existRESTfulHTTPRule := false }} +{{- range $service := .Services }} + {{- range $rpc := $service.RPC }} + {{- if ne (len .RESTfulAPIInfo.ContentList) 0 }} + {{- $existRESTfulHTTPRule = true}} + {{- end }} + {{- if or $rpc.ClientStreaming $rpc.ServerStreaming }} + {{- $importStream = true }} + {{- end }} + {{- end }} +{{- end }} + +{{- /* $goPkgName example: "greeter" */}} +package {{ $goPkgName }} + +import ( + "context" + "fmt" + + _ "{{ $domainName }}/trpc-go/trpc-go" + _ "{{ $domainName }}/trpc-go/trpc-go/http" + + {{ if $existRESTfulHTTPRule }} + "{{ $domainName }}/trpc-go/trpc-go/restful" + {{ end }} + + {{ if and (ne .Protocol "trpc") (ne .Protocol "http") }} + "{{ $domainName }}/trpc-go/trpc-codec/{{.Protocol}}" + {{ end }} + + "{{ $domainName }}/trpc-go/trpc-go/server" + "{{ $domainName }}/trpc-go/trpc-go/client" + "{{ $domainName }}/trpc-go/trpc-go/codec" + {{- if $importStream }} + "{{ $domainName }}/trpc-go/trpc-go/stream" + {{- end }} + +{{- /* .Imports example: "trpc.group/trpcprotocol/testapp/testserver2" */}} + {{ range .Imports }} + {{ if ne $goPkgName . }} + {{ if contains . ";" }} + {{ $val := (splitList ";" .) }} + {{ index $val 1}} "{{index $val 0}}" + {{ else }} + "{{- . -}}" + {{ end }} + {{ end }} + {{ end }} + flatbuffers "github.com/google/flatbuffers/go" +) + +/* ************************************ Service Definition ************************************ */ + +{{- /* $svrName example: Greeter */}} +{{- /* $svrNameCamelCase example: Greeter */}} +{{ range $service := .Services }} +{{- $svrName := $service.Name -}} +{{- $svrNameCamelCase := $service.Name|camelcase -}} + +{{- $serviceStream := false }} +{{- range $rpc := $service.RPC }} +{{- if or $rpc.ClientStreaming $rpc.ServerStreaming }} +{{- $serviceStream = true }} +{{- end }} +{{- end }} + +{{- /* $svrNameCamelCase example: Greeter */}} +// {{$svrNameCamelCase}}{{$serviceSuffix}} defines service +type {{$svrNameCamelCase}}{{$serviceSuffix}} interface { + {{- /* $rpcName example: SayHello */}} + {{- /* .RequestType example: HelloRequest */}} + {{- /* .ResponseType example: HelloReply */}} + {{ range $rpc := $service.RPC }} + {{- $rpcName := .Name | camelcase -}} + {{- /* $rpcReqType example: HelloRequest */}} + {{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- /* $rpcRspType example: HelloReply */}} + {{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{ with .LeadingComments }}// {{$rpcName}} {{.}}{{ end }} + {{- if $rpc.ClientStreaming }} + {{- /* SayHello(Greeter_SayHelloServer) error */}} + {{$rpcName}}({{$svrNameCamelCase}}_{{$rpcName}}Server) error {{ with .TrailingComments}}// {{.}}{{ end }} + {{- else }} + {{- if $rpc.ServerStreaming }} + {{- /* SayHello(*HelloRequest, Greeter_SayHelloServerStreamServer) error */}} + {{$rpcName}}(*{{$rpcReqType}}, {{$svrNameCamelCase}}_{{$rpcName}}Server) error {{ with .TrailingComments}}// {{.}}{{ end }} + {{- else }} + {{- /* SayHello(ctx context.Context, req *HelloRequest) (*flatbuffers.Builder, error) */}} + {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}) (*flatbuffers.Builder, error) {{ with .TrailingComments}}// {{.}}{{ end }} + {{- end }} + {{- end }} + {{ end -}} +} + +{{range $service.RPC -}} +{{- /* $rpcName example: SayHello */}} +{{- $rpcName := .Name | camelcase -}} +{{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} +{{- if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} +{{- /* func GreeterService_SayHello_Handler(svr interface{}, ctx context.Context, f server.FilterFunc) (..) */}} +func {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler(svr interface{}, ctx context.Context, f server.FilterFunc) (interface{}, error) { + {{- /* req := &HelloRequest{} */}} + req := &{{$rpcReqType}}{} + filters, err := f(req) + if err != nil { + return nil, err + } + + handleFunc := func(ctx context.Context, reqbody interface{}) (interface{}, error) { + {{- /* return svr.(GreeterServuce).SayHello(ctx, reqbody.(*HelloRequest)) */}} + return svr.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(ctx, reqbody.(*{{$rpcReqType}})) + } + + {{ if eq $protocol "grpc" }} + // get req from ctx + grpcData := ctx.Value(grpc.ContextKeyHeader).(*grpc.Header) + req = grpcData.Req.(*{{$rpcReqType}}) + {{ end }} + + value, err := filters.Filter(ctx, req, handleFunc) + if err != nil { + return nil, err + } + rsp, ok := value.(*flatbuffers.Builder) + if !ok { + return nil, fmt.Errorf("unknow rsp value type: %T", value) + } + + {{ if eq $protocol "grpc" }} + // set rsp to ctx, and set rsp empty + grpcData.Rsp = rsp + rsp = &flatbuffers.Builder{} + {{ end }} + + return rsp, nil +} +{{- else }} +{{- /* func GreeterService_SayHelloServerStream_Handler(srv interface{}, stream server.Stream) error { */}} +func {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler(srv interface{}, stream server.Stream) error { + {{- if (ne .ClientStreaming true) }} + {{- /* m := new(HelloRequest) */}} + m := new({{$rpcReqType}}) + if err := stream.RecvMsg(m); err != nil { return err } + {{- /* return srv.(GreeterService).SayHelloServerStream(m, &greeterSayHelloServerStreamServer{stream}) */}} + return srv.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(m, &{{$svrNameCamelCase|untitle}}{{$rpcName}}Server{stream}) + {{- else }} + {{- /* .ClientStreaming is true */}} + {{- /* return srv.(GreeterService).SayHelloServerStream(&greeterSayHelloServerStreamServer{stream}) */}} + return srv.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(&{{$svrNameCamelCase|untitle}}{{$rpcName}}Server{stream}) + {{- end }} +} +{{ $genSend := .ServerStreaming }} +{{- $genSendAndClose := not .ServerStreaming -}} +{{- $genRecv := .ClientStreaming -}} +{{- /* type Greeter_SayHelloServerStreamServer interface { */}} +type {{$svrNameCamelCase}}_{{$rpcName}}Server interface { + {{- if $genSend }} + {{- /* Send(*flatbuffers.Builder) */}} + Send(*flatbuffers.Builder) error + {{- end }} + {{- if $genSendAndClose }} + {{- /* SendAndClose(*flatbuffers.Builder) */}} + SendAndClose(*flatbuffers.Builder) error + {{- end }} + {{- if $genRecv }} + {{- /* Recv() (*HelloRequest, error) */}} + Recv() (*{{$rpcReqType}}, error) + {{- end }} + server.Stream +} +{{- /* type greeter_SayHelloServerStreamServer struct { */}} +type {{$svrNameCamelCase|untitle}}{{$rpcName}}Server struct { + server.Stream +} + +{{ if $genSend }} +{{- /* func (x *greeter_SayHelloServerStreamServer) Send(m *flatbuffers.Builder) */}} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) Send(m *flatbuffers.Builder) error { + return x.Stream.SendMsg(m) +} +{{ end }} + +{{ if $genSendAndClose }} +{{- /* func(x *greeter_SayHelloServerStreamServer) SendAndClose(m *flatbuffers.Builder) */}} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) SendAndClose(m *flatbuffers.Builder) error { + return x.Stream.SendMsg(m) +} +{{ end }} + +{{ if $genRecv }} +{{- /* func (x *greeter_SayHelloServerStreamServer) Recv() (*HelloRequest, error) { */}} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) Recv() (*{{$rpcReqType}}, error) { + {{- /* m := new(HelloRequest) */}} + m := new({{$rpcReqType}}) + if err := x.Stream.RecvMsg(m); err != nil { return nil, err } + return m, nil +} +{{ end }} +{{- end }} +{{end -}} + +{{- range $service.RPC -}} +{{- $rpcName := .Name | camelcase }} +{{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + +{{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} +{{- range $index, $content := .RESTfulAPIInfo.ContentList -}} +{{- if $content.RequestBody}} +// requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} {{$content.Method}}: {{$content.PathTmpl}} +type requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} struct{} + +func (requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Locate(message restful.ProtoMessage) interface{} { + x := message.(*{{$rpcReqType}}) + {{- if eq $content.RequestBody "*"}} + return x + {{- else}} + return &x.{{camelcase $content.RequestBody}} + {{- end}} +} + +func (requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Body() string { + return "{{$content.RequestBody}}" +} +{{- end -}} + +{{- if $content.ResponseBody}} +// responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} {{$content.Method}}: {{$content.PathTmpl}} +type responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} struct{} + +func (responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Locate(message restful.ProtoMessage) interface{} { + x := message.(*{{$rpcRspType}}) + {{- if eq $content.ResponseBody "*"}} + return x + {{- else}} + return &x.{{camelcase $content.ResponseBody}} + {{- end}} +} + +func (responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) ResponseBody() string { + return "{{$content.ResponseBody}}" +} + +{{end}} +{{end}} +{{end}} +{{end}} + +// {{$svrNameCamelCase}}Server_ServiceDesc descriptor for server.RegisterService +{{- /* var GreeterServer_ServiceDesc = server.ServiceDesc { */}} +var {{$svrNameCamelCase}}Server_ServiceDesc = server.ServiceDesc { + ServiceName: " + {{- if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$service.Name -}} + {{- else -}} + {{- $pkgName}}.{{$service.Name -}} + {{- end}}", + {{- /* HandlerType: ((*GreeterService)(nil)), */}} + HandlerType: ((*{{$svrNameCamelCase}}{{$serviceSuffix}})(nil)), + {{- if $serviceStream }} + StreamHandle: stream.NewStreamDispatcher(), + {{- end }} + Methods: []server.Method{ + {{- range $service.RPC}} + {{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + {{- $rpcName := .Name | camelcase }} + { + {{- /* Name: "/trpc.testapp.greeter.Greeter/SayHello", */}} + Name: "{{.FullyQualifiedCmd}}", + {{- /* Func: GreeterService_SayHello_handler, */}} + Func: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + {{if .RESTfulAPIInfo.ContentList }} + {{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{- $fullyQualifiedCmd := .FullyQualifiedCmd -}} + Bindings: []*restful.Binding{ + {{- range $index, $content := .RESTfulAPIInfo.ContentList -}} + { + Name: "{{$fullyQualifiedCmd}}", + Input: func() restful.ProtoMessage { return new({{$rpcReqType}}) }, + Filter: func(svc interface{}, ctx context.Context, reqbody interface{}) (interface{}, error) { + return svc.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(ctx, reqbody.(*{{$rpcReqType}})) + }, + HTTPMethod: "{{$content.Method}}", + Pattern: restful.Enforce("{{$content.PathTmpl}}"), + Body: {{ if $content.RequestBody -}} + requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}{} + {{- else -}} + nil + {{- end}}, + ResponseBody: {{ if $content.ResponseBody -}} + responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}{} + {{- else}} + nil + {{- end}}, + }, + {{- end -}} + }, + {{ end }} + }, + {{- end }} + {{- end}} + {{- range $service.RPCx }} + {{- $rpcName := .Name | camelcase -}} + { + Name: "{{.FullyQualifiedCmd}}", + Func: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + }, + {{ end }} + }, + {{- if $serviceStream }} + Streams: []server.StreamDesc{ + {{- range $service.RPC}} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $rpcName := .Name | camelcase }} + { + StreamName: "{{.FullyQualifiedCmd}}", + Handler: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + ServerStreams: {{ .ServerStreaming }}, + }, + {{- end }} + {{- end}} + }, + {{- end }} +} + +// Register{{$svrNameCamelCase}}{{$serviceSuffix}} register service +{{- /* func RegisterGreeterService(s server.Service, svr GreeterService) { */}} +func Register{{$svrNameCamelCase}}{{$serviceSuffix}}(s server.Service, svr {{$svrNameCamelCase}}{{$serviceSuffix}}) { + if err := s.Register(&{{$svrNameCamelCase}}Server_ServiceDesc, svr); err != nil { + panic(fmt.Sprintf("{{$svrNameCamelCase}} register error:%v", err)) + } + + {{ if eq $protocol "grpc" }} + // register service to grpc + if err := grpc.Register({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName, + "{{$fbsfile}}", + []grpc.RegisterMethodsInfo{ + {{- range $service.RPC}} + {{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + {{- $rpcName := .Name | camelcase }} + { + Method: server.Method{ + Name: "{{$rpcName}}", + Func: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + }, + ReqType: reflect.TypeOf({{$rpcReqType}}{}), + RspType: reflect.TypeOf({{$rpcRspType}}{}), + }, + {{- end }} + {{- end }} + }); err != nil { + panic(fmt.Sprintf("grpc register {{$svrNameCamelCase}} error:%v", err)) + } + {{ end }} +} + +{{ end }} + +/* ************************************ Client Definition ************************************ */ + +{{ range $service := .Services }} +{{ $svrNameCamelCase := $service.Name | camelcase }} + +// {{$svrNameCamelCase}}ClientProxy defines service client proxy +{{- /* type GreeterClientProxy interface { */}} +type {{$svrNameCamelCase}}ClientProxy interface { + {{ range $rpc := $service.RPC}} + {{- $rpcName := .Name | camelcase -}} + {{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{ with .LeadingComments }}// {{$rpcName}} {{.}}{{ end }} + {{- if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} + {{- /* SayHello(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) (rsp *HelloReply, err error) */}} + {{$rpcName}}(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) (rsp *{{$rpcRspType}}, err error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- else }} + {{- if .ClientStreaming }} + {{- /* SayHelloClientStream(ctx context.Context, opts ...client.Option) (Greeter_SayHelloClientStreamClient, err error) */}} + {{$rpcName}}(ctx context.Context, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- else }} + {{- /* SayHelloServerStream(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) (Greeter_SayHelloServerStreamClient, err error) */}} + {{$rpcName}}(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- end }} + {{- end }} +{{ end -}} +} + +type {{$svrNameCamelCase}}ClientProxyImpl struct{ + client client.Client + {{- if $importStream }} + streamClient stream.Client + {{- end }} + opts []client.Option +} + +var New{{$svrNameCamelCase}}ClientProxy = func(opts...client.Option) {{$svrNameCamelCase}}ClientProxy { + {{- if $importStream }} + return &{{$svrNameCamelCase}}ClientProxyImpl {client: client.DefaultClient, streamClient: stream.DefaultStreamClient, opts: opts} + {{- else }} + return &{{$svrNameCamelCase}}ClientProxyImpl {client: client.DefaultClient, opts: opts} + {{- end }} +} + +{{range $rpc := $service.RPC}} +{{- $rpcName := .Name | camelcase -}} +{{- $rpcReqType := (simplify (gofulltype .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltype .ResponseType $.FileDescriptor) $goPkgName)|export }} +{{ if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) (*{{$rpcRspType}}, error) { + + {{ if eq $protocol "grpc" }} + // set req to ctx + h := ctx.Value(grpc.ContextKeyHeader) + var header *grpc.Header + if h == nil { + header = &grpc.Header{} + ctx = context.WithValue(ctx, grpc.ContextKeyHeader, header) + } else { + var ok bool + header, ok = h.(*grpc.Header) + if !ok { + return nil, errors.New(fmt.Sprintf("grpc header in context cannot be transferred to grpc.Header")) + } + } + header.Req = req + header.Rsp = &{{$rpcRspType}}{} + {{ end }} + + ctx, msg := codec.WithCloneMessage(ctx) + defer codec.PutBackMessage(msg) + + msg.WithClientRPCName("{{.FullyQualifiedCmd}}") + msg.WithCalleeServiceName({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName) + msg.WithCalleeApp("{{$appName}}") + msg.WithCalleeServer("{{$serverName}}") + msg.WithCalleeService("{{$service.Name}}") + msg.WithCalleeMethod("{{$rpcName}}") + msg.WithSerializationType(codec.SerializationTypeFlatBuffer) + + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + {{ if eq $protocol "grpc" }} + callopts = append(callopts, client.WithProtocol("grpc")) + {{ end }} + rsp := &{{$rpcRspType}}{} + + if err := c.client.Invoke(ctx, req, rsp, callopts...); err != nil { + return nil, err + } + + {{ if eq $protocol "grpc" }} + // get rsp from ctx + *rsp = *header.Rsp.(*{{$rpcRspType}}) + {{ end }} + + return rsp, nil +} +{{ else }} +{{- if .ClientStreaming }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) { +{{- else }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, req *flatbuffers.Builder, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) { +{{- end }} + + ctx, msg := codec.WithCloneMessage(ctx) + + msg.WithClientRPCName("{{.FullyQualifiedCmd}}") + msg.WithCalleeServiceName({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName) + msg.WithCalleeApp("{{$appName}}") + msg.WithCalleeServer("{{$serverName}}") + msg.WithCalleeService("{{$service.Name}}") + msg.WithCalleeMethod("{{$rpcName}}") + msg.WithSerializationType(codec.SerializationTypeFlatBuffer) + + clientStreamDesc := &stream.ClientStreamDesc{} + clientStreamDesc.StreamName = "{{.FullyQualifiedCmd}}" + clientStreamDesc.ClientStreams = true + + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + + stream, err := c.streamClient.NewStream(ctx, clientStreamDesc, "{{.FullyQualifiedCmd}}", callopts...) + if err != nil { + return nil, err + } + x := &{{$svrNameCamelCase|untitle}}{{$rpcName}}Client{stream} + {{- if and (ne .ClientStreaming true) .ServerStreaming }} + if err := x.ClientStream.SendMsg(req); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + {{- end }} + + return x, nil +} +{{ $genSend := .ClientStreaming }} +{{ $genRecv := .ServerStreaming }} +{{ $genCloseAndRecv := not .ServerStreaming }} +type {{$svrNameCamelCase}}_{{$rpcName}}Client interface { + {{- if $genSend }} + Send(*flatbuffers.Builder) error + {{- end }} + {{- if $genRecv }} + Recv() (*{{$rpcRspType}}, error) + {{- end }} + {{- if $genCloseAndRecv }} + CloseAndRecv() (*{{$rpcRspType}}, error) + {{- end }} + stream.ClientStream +} + +type {{$svrNameCamelCase|untitle}}{{$rpcName}}Client struct { + stream.ClientStream +} +{{ if $genSend }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) Send(m *flatbuffers.Builder) error { + return x.ClientStream.SendMsg(m) +} +{{ end }} +{{ if $genRecv}} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) Recv() (*{{$rpcRspType}}, error) { + m := new({{$rpcRspType}}) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} +{{ end }} +{{ if $genCloseAndRecv }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) CloseAndRecv() (*{{$rpcRspType}}, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new({{$rpcRspType}}) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} +{{ end }} +{{ end }} +{{end}} + +{{ end }} diff --git a/install/flatbuffers/asset_go/service_rpc.go.tpl b/install/flatbuffers/asset_go/service_rpc.go.tpl new file mode 100755 index 0000000..41758f0 --- /dev/null +++ b/install/flatbuffers/asset_go/service_rpc.go.tpl @@ -0,0 +1,173 @@ +{{ $domainName := .Domain }} + +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgName = . -}} +{{- end -}} +package main + +import ( + "context" + {{- $importio := false }} + {{- range (index .Services .ServiceIndex).RPC }} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $importio = true }} + {{- end }} + {{- end }} + {{- if $importio }} + "io" + {{- end }} + + flatbuffers "github.com/google/flatbuffers/go" + fb "{{$goPkgName}}" + "{{$domainName}}/trpc-go/trpc-go/log" + + {{ range $.Imports }} + {{/* In the case of explicitly specifying importName, for example: import "{{ $domainName }}/..../structpb;xxx" */}} + {{ if contains . ";" }} + {{ $val := (splitList ";" .) }} + {{ index $val 1}} "{{index $val 0}}" + {{ else }} + "{{- . -}}" + {{ end }} + {{ end }} +) + +{{/* ".ServiceIndex" remains valid regardless of how the files are divided. */}} +{{ $service := (index .Services .ServiceIndex) -}} +{{- $svrName := $service.Name | camelcase | untitle -}} +{{- $svrNameCamelCase := $service.Name|camelcase -}} + +{{/* Generate the Service type definition when .MethodIndex is less than or equal to 0, regardless of how the files are divided. */}} +{{- if le $.MethodIndex 0 }} +type {{$svrName}}Impl struct {} +{{- end }} + +{{/* During the current loop, the execution is necessary if the files are not divided by method, or if the index value passed when dividing the files by method needs to be executed. */}} +{{ range $index, $method := $service.RPC }} + +{{ if or (not $.PerMethod) (eq $.MethodIndex $index) }} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "fb.%s" (splitList "." $rpcReqType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltype $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "fb.%s" (splitList "." $rpcRspType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltype $rpcRspType $.FileDescriptor) -}} +{{- end -}} + +{{ with .LeadingComments }}// {{$rpcName}} {{.}}{{ end }} +{{- if and $method.ClientStreaming $method.ServerStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Bidirectional streaming scenario processing logic (for reference only, please modify as needed). + for { + req, err := stream.Recv() + log.Debugf("Bidi server receive %v", req) + if err == io.EOF { + return nil + } + if err != nil { + return err + } + b := flatbuffers.NewBuilder(0) + for _, greeting := range [...]string{"Hello", "Hi ", "Hola "} { + log.Debugf("Bidi server is about to send %v", greeting) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("%v %v", greeting, string(req.Message()))) + {{$rpcRspType}}Start(b) + // {{$rpcRspType}}AddMessage(b, idx) + b.Finish({{$rpcRspType}}End(b)) + if err := stream.Send(b); err != nil { + return err + } + } + } +} +{{- else if $method.ClientStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Client streaming scenario processing logic (for reference only, please modify as needed). + // all := []string{} + for { + req, err := stream.Recv() + log.Debugf("StreamClient server receive %v", req) + if err == io.EOF { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(strings.Join(all, ", ")) + {{$rpcRspType}}Start(b) + // {{$rpcRspType}}AddMessage(b, idx) + b.Finish({{$rpcRspType}}End(b)) + return stream.SendAndClose(b) + } + if err != nil { + return err + } + // Replace 'Message' with the field name you want to operate on. + // all = append(all, string(req.Message())) + } +} +{{- else if $method.ServerStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(req *{{$rpcReqType}}, stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Server streaming scenario processing logic (for reference only, please modify as needed). + log.Debugf("StreamClient server receive %v", req) + for i := 0; i < 5; i++ { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("Hello %v %v", string(req.Message()), i)) + {{$rpcRspType}}Start(b) + // {{$rpcRspType}}AddMessage(b, idx) + b.Finish({{$rpcRspType}}End(b)) + if err := stream.Send(b); err != nil { + return err + } + } + return nil +} +{{- else }} +func (s *{{$svrName}}Impl) {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}) (*flatbuffers.Builder, error) { + // Unary call: flatbuffers processing logic (for reference only, please modify as needed). + log.Debugf("Simple server receive %v", req) + // Replace 'Message' with the field name you want to operate on. + // v := req.Message() // Get Message field of request. + // var m string + // if v == nil { + // m = "Unknown" + // } else { + // m = string(v) + // } + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString("welcome " + m) // Create a string in flatbuffers. + b := &flatbuffers.Builder{} + {{$rpcRspType}}Start(b) + // {{$rpcRspType}}AddMessage(b, idx) + b.Finish({{$rpcRspType}}End(b)) + return b, nil +} +{{- end }} +{{- end }} +{{- end }} diff --git a/install/flatbuffers/asset_go/service_rpc_test.go.tpl b/install/flatbuffers/asset_go/service_rpc_test.go.tpl new file mode 100755 index 0000000..81aaafb --- /dev/null +++ b/install/flatbuffers/asset_go/service_rpc_test.go.tpl @@ -0,0 +1,404 @@ +{{ $domainName := .Domain }} + +{{- $svrNameCamelCase := (index .Services .ServiceIndex).Name | camelcase -}} +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} +{{- $goPkgName = . -}} +{{- end -}} + +{{ $fname := (basenamewithoutext .FilePath) -}} +{{- $serviceIndex := .ServiceIndex -}} +{{ $service := (index .Services .ServiceIndex) -}} + +package main + +import ( + "context" + {{- $importio := false }} + {{- range (index .Services .ServiceIndex).RPC }} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $importio = true }} + {{- end }} + {{- end }} + {{- if $importio }} + "io" + {{- end }} + "testing" + + trpc "{{ $domainName }}/trpc-go/trpc-go" + _ "{{ $domainName }}/trpc-go/trpc-go/http" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + + flatbuffers "github.com/google/flatbuffers/go" + fb "{{$goPkgName}}" + + {{ range .Imports }} + {{ if contains . ";" }} + {{ $val := (splitList ";" .) }} + {{ index $val 1}} "{{index $val 0}}" + {{ else }} + "{{- . -}}" + {{ end }} + {{- end }} +) + +{{$svrName := $service.Name | camelcase | untitle}} +{{ $commaSeparated := (print ($svrName|title) "ClientProxy")}} + +{{- range (index .Services .ServiceIndex).RPC }} +{{- if or .ClientStreaming .ServerStreaming }} +{{- $rpcName := .Name | camelcase -}} + +{{- $commaSeparated = (print $commaSeparated "," $svrNameCamelCase "_" $rpcName "Client") }} +{{- $commaSeparated = (print $commaSeparated "," $svrNameCamelCase "_" $rpcName "Server") }} +{{- end }} +{{- end }} + +//go:generate go mod tidy +{{ $p1 := trimright ";" $goPkgName }} +{{ $p2 := splitList ";" $goPkgName | last | gopkg_simple }} +//go:generate mockgen -destination=stub/{{$p1}}/{{$fname}}_mock.go -package={{$p2}} -self_package={{$p1}} --source=stub/{{$p1}}/{{$fname}}.trpc.go + +{{range $index, $method := (index .Services .ServiceIndex).RPC}} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "fb.%s" (splitList "." $rpcReqType |last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltype $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "fb.%s" (splitList "." $rpcRspType |last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltype $rpcRspType $.FileDescriptor) -}} +{{- end -}} + +{{- /* $reqType and $rspType are the underscored versions of $rpcReqType and $rpcRspType, used for naming xxFromBuilder functions. */ -}} +{{- $reqType := (printf "%s_%s_%s" $svrNameCamelCase $rpcName ($rpcReqType | gopkg) ) -}} +{{- $rspType := (printf "%s_%s_%s" $svrNameCamelCase $rpcName ($rpcRspType | gopkg) ) -}} +// {{$reqType}}FromBuilder retrieves the corresponding structure of the Request from the *flatbuffers.Builder type. +func {{$reqType}}FromBuilder(b *flatbuffers.Builder) *{{$rpcReqType}} { + // By calling b.FinishedBytes, you can obtain the byte stream corresponding to Marshal. + reqbytes := b.FinishedBytes() + req := &{{$rpcReqType}}{} + // Calling Init allows you to construct a Request from a byte stream, which is equivalent to Unmarshal. + req.Init(reqbytes, flatbuffers.GetUOffsetT(reqbytes)) + return req +} + +// {{$rspType}}FromBuilder retrieves the corresponding structure of the Reply from the *flatbuffers.Builder type. +func {{$rspType}}FromBuilder(b *flatbuffers.Builder) *{{$rpcRspType}} { + // By calling b.FinishedBytes, you can obtain the byte stream corresponding to Marshal. + rspbytes := b.FinishedBytes() + rsp := &{{$rpcRspType}}{} + // Calling Init allows you to construct a Reply from a byte stream, which is equivalent to Unmarshal. + rsp.Init(rspbytes, flatbuffers.GetUOffsetT(rspbytes)) + return rsp +} + +{{- if and .ClientStreaming .ServerStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := fb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderClient := make([]*gomock.Call, 0) + inorderServer := make([]*gomock.Call, 0) + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any()).AnyTimes() + m.DoAndReturn(func(ctx context.Context, opts ...interface{}) (interface{}, error) { + x := {{$rpcName|untitle}}Client.EXPECT().Send(gomock.Any()).AnyTimes() + x.DoAndReturn(func(req interface{}) error { + b, ok := req.(*flatbuffers.Builder) + if !ok { + panic("invalid request") + } + s := {{$rpcName|untitle}}Server.EXPECT().Recv().Return({{$reqType}}FromBuilder(b), nil) + inorderServer = append(inorderServer, s) + return nil + }) + k := {{$rpcName|untitle}}Client.EXPECT().CloseSend() + k.DoAndReturn(func() error { + {{$rpcName|untitle}}Server.EXPECT().Recv().Return(nil, io.EOF) + err := {{$svrName}}Service.{{$rpcName}}({{$rpcName|untitle}}Server) + if err != nil { + return err + } + {{$rpcName|untitle}}Client.EXPECT().Recv().Return(nil, io.EOF) + return nil + }) + return {{$rpcName|untitle}}Client, nil + }) + gomock.InOrder(inorderServer...) + s := {{$rpcName|untitle}}Server.EXPECT().Send(gomock.Any()).AnyTimes() + s.DoAndReturn(func(rsp interface{}) error { + b, ok := rsp.(*flatbuffers.Builder) + if !ok { + panic("invalid response") + } + c := {{$rpcName|untitle}}Client.EXPECT().Recv().Return({{$rspType}}FromBuilder(b), nil) + inorderClient = append(inorderClient, c) + return nil + }) + gomock.InOrder(inorderClient...) + // Start writing unit test logic (for reference only, please modify as needed). + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext()) + require.Nil(t, err) + require.NotNil(t, stream) + for i := 0; i < 5; i++ { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("D %v", i)) + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, idx) + b.Finish({{$rpcReqType}}End(b)) + // Output each input parameter (check t.Logf output, run `go test -v`). + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %q", {{$reqType}}FromBuilder(b).Message()) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %v", {{$reqType}}FromBuilder(b)) + err := stream.Send(b) + require.Nil(t, err) + } + err = stream.CloseSend() + require.Nil(t, err) + for { + rsp, err := stream.Recv() + if err == io.EOF { + break + } + // Output each return value (check t.Logf output, run `go test -v`). + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %q, err: %v", rsp.Message(), err) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + require.Nil(t, err) + } +} +{{ else }} +{{ if .ClientStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := fb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderServer := make([]*gomock.Call, 0) + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any()).AnyTimes() + m.DoAndReturn(func(ctx context.Context, opts ...interface{}) (interface{}, error) { + x := {{$rpcName|untitle}}Client.EXPECT().Send(gomock.Any()).AnyTimes() + x.DoAndReturn(func(req interface{}) error { + b, ok := req.(*flatbuffers.Builder) + if !ok { + panic("invalid request") + } + s := {{$rpcName|untitle}}Server.EXPECT().Recv().Return({{$reqType}}FromBuilder(b), nil) + inorderServer = append(inorderServer, s) + return nil + }) + k := {{$rpcName|untitle}}Client.EXPECT().CloseAndRecv() + k.DoAndReturn(func() (interface{}, error) { + rsp := &{{$rpcRspType}}{} + {{$rpcName|untitle}}Server.EXPECT().Recv().Return(nil, io.EOF) + s := {{$rpcName|untitle}}Server.EXPECT().SendAndClose(gomock.Any()) + s.DoAndReturn(func(f interface{}) error { + b, ok := f.(*flatbuffers.Builder) + if !ok { + panic("invalid response") + } + rsp = {{$rspType}}FromBuilder(b) + return nil + }) + err := {{$svrName}}Service.{{$rpcName}}({{$rpcName|untitle}}Server) + if err != nil { + return nil, err + } + return rsp, nil + }) + return {{$rpcName|untitle}}Client, nil + }) + gomock.InOrder(inorderServer...) + // Start writing unit test logic (for reference only, please modify as needed). + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext()) + require.Nil(t, err) + require.NotNil(t, stream) + for i := 0; i < 5; i++ { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // idx := b.CreateString(fmt.Sprintf("B %v", i)) + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, idx) + b.Finish({{$rpcReqType}}End(b)) + // Output each input parameter (check t.Logf output, run `go test -v`). + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %q", {{$reqType}}FromBuilder(b).Message()) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %q", {{$reqType}}FromBuilder(b)) + err := stream.Send(b) + require.Nil(t, err) + } + rsp, err := stream.CloseAndRecv() + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %q, err: %v", rsp.Message(), err) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + require.Nil(t, err) +} +{{ else }} +{{ if .ServerStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := fb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := fb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderClient := make([]*gomock.Call, 0) + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + m.DoAndReturn(func(ctx context.Context, req interface{}, opts ...interface{}) (interface{}, error) { + b, ok := req.(*flatbuffers.Builder) + if !ok { + panic("invalid request") + } + s := {{$rpcName|untitle}}Server.EXPECT().Send(gomock.Any()).AnyTimes() + s.DoAndReturn(func(rsp interface{}) error { + b, ok := rsp.(*flatbuffers.Builder) + if !ok { + panic("invalid response") + } + c := {{$rpcName|untitle}}Client.EXPECT().Recv().Return({{$rspType}}FromBuilder(b), nil) + inorderClient = append(inorderClient, c) + return nil + }) + err := {{$svrName}}Service.{{$rpcName}}({{$reqType}}FromBuilder(b), {{$rpcName|untitle}}Server) + if err != nil { + return nil, err + } + {{$rpcName|untitle}}Client.EXPECT().Recv().Return(nil, io.EOF) + return {{$rpcName|untitle}}Client, nil + }) + gomock.InOrder(inorderClient...) + // Start writing unit test logic (for reference only, please modify as needed). + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // i := b.CreateString("C") + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, i) + b.Finish({{$rpcReqType}}End(b)) + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %q", {{$reqType}}FromBuilder(b).Message()) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %v", {{$reqType}}FromBuilder(b)) + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext(), b) + require.Nil(t, err) + require.NotNil(t, stream) + for { + rsp, err := stream.Recv() + if err == io.EOF { + break + } + // The Message field can be modified as needed. + // t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %q, err: %v", rsp.Message(), err) + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + require.Nil(t, err) + } +} +{{ else }} +// As an example, create{{$reqType}} creates a string in flatbuffers +// and uses that string as the Message field in the Request. +// During development, replace the Message field with the desired field +// to be constructed, and replace String with the corresponding field type. +func create{{$reqType}}(s string) *{{$rpcReqType}} { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // i := b.CreateString(s) + {{$rpcReqType}}Start(b) + // {{$rpcReqType}}AddMessage(b, i) + b.Finish({{$rpcReqType}}End(b)) + return {{$reqType}}FromBuilder(b) +} +func create{{$rspType}}(s string) *{{$rpcRspType}} { + b := flatbuffers.NewBuilder(0) + // Example of Adding a Field. + // Replace the "String" in CreateString with the field type you want to work with. + // Replace "Message" in AddMessage with the field name you want to work with. + // i := b.CreateString(s) + {{$rpcRspType}}Start(b) + // {{$rpcRspType}}AddMessage(b, i) + b.Finish({{$rpcRspType}}End(b)) + return {{$rspType}}FromBuilder(b) +} +func Test_{{$svrNameCamelCase|untitle}}Impl_{{$rpcName}}(t *testing.T) { + type args struct { + ctx context.Context + req *{{$rpcReqType}} + rsp *{{$rpcRspType}} + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + // Here's an example that you can modify according to your needs. + { + name: "basic test", + args: args{ + ctx: trpc.BackgroundContext(), + req: create{{$reqType}}("A"), + rsp: create{{$rspType}}("welcome A"), + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + {{- $svrName := $service.Name | camelcase | untitle}} + s := &{{$svrName}}Impl{} + b := &flatbuffers.Builder{} + var err error + if b, err = s.{{$rpcName}}(tt.args.ctx, tt.args.req); (err != nil) != tt.wantErr { + t.Errorf("{{$svrNameCamelCase|untitle}}Impl.{{$rpcName}}() error = %v, wantErr %v", err, tt.wantErr) + } + rsp := {{$rspType}}FromBuilder(b) + if !reflect.DeepEqual(rsp, tt.args.rsp) { + // The Message field can be modified as needed. + // t.Errorf("{{$svrNameCamelCase|untitle}}Impl.{{$rpcName}}() rsp got = %q, want %q", rsp.Message(), tt.args.rsp.Message()) + t.Errorf("{{$svrNameCamelCase|untitle}}Impl.{{$rpcName}}() rsp got = %v, want %v", rsp, tt.args.rsp) + } + }) + } +} +{{ end }} +{{ end }} +{{- end }} +{{end}} diff --git a/install/flatbuffers/asset_go/trpc_go.yaml b/install/flatbuffers/asset_go/trpc_go.yaml new file mode 100755 index 0000000..aa7a3be --- /dev/null +++ b/install/flatbuffers/asset_go/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/install/protobuf/asset_cpp/.bazelrc b/install/protobuf/asset_cpp/.bazelrc new file mode 100644 index 0000000..91f3db0 --- /dev/null +++ b/install/protobuf/asset_cpp/.bazelrc @@ -0,0 +1,3 @@ +build --cxxopt="--std=c++17" +# Comment below line and add `build --copt=-g --strip=never` to enable debug +build --copt=-O2 \ No newline at end of file diff --git a/install/protobuf/asset_cpp/.clang-format b/install/protobuf/asset_cpp/.clang-format new file mode 100644 index 0000000..5157839 --- /dev/null +++ b/install/protobuf/asset_cpp/.clang-format @@ -0,0 +1,14 @@ +Language: Cpp +BasedOnStyle: Google +ColumnLimit: 100 + +# Automatically detect pointer alignment in the code. +# If you want to enforce uniformity, you can change it to false. +DerivePointerAlignment: true + +# By default, the alignment is based on the type name. +PointerAlignment: Left + +# Only sort headers in each include block +SortIncludes: true +IncludeBlocks: Preserve diff --git a/install/protobuf/asset_cpp/README.md b/install/protobuf/asset_cpp/README.md new file mode 100644 index 0000000..5ff4d1a --- /dev/null +++ b/install/protobuf/asset_cpp/README.md @@ -0,0 +1,9 @@ +# Usage + +- You can directly compile and run via scripts `run_server.sh` and `run_client.sh`. +- You can only do compile via script `build.sh` and check the binary generated at bazel-bin. The raw command to run server and client is like below, you are free to check the yaml file too: +```bash +./bazel-bin/server/server_bin --config=server/conf/trpc_cpp_fiber.yaml +./bazel-bin/client/fiber_client --client_config=client/conf/trpc_cpp_fiber.yaml +``` +- You can clean all the resources build out via script `clean.sh`. diff --git a/install/protobuf/asset_cpp/WORKSPACE b/install/protobuf/asset_cpp/WORKSPACE new file mode 100644 index 0000000..aebd35a --- /dev/null +++ b/install/protobuf/asset_cpp/WORKSPACE @@ -0,0 +1,14 @@ +load('@bazel_tools//tools/build_defs/repo:git.bzl', 'git_repository') +git_repository( + name = "trpc_cpp", + remote = "https://git.woa.com/trpc-cpp/open-source/trpc-cpp.git", + branch = "master", +) +load("@trpc_cpp//trpc:workspace.bzl", "trpc_workspace") + +trpc_workspace() + +local_repository( + name = "proto", + path = "./proto", +) \ No newline at end of file diff --git a/install/protobuf/asset_cpp/build.sh b/install/protobuf/asset_cpp/build.sh new file mode 100755 index 0000000..73846c0 --- /dev/null +++ b/install/protobuf/asset_cpp/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bazel build ... diff --git a/install/protobuf/asset_cpp/clean.sh b/install/protobuf/asset_cpp/clean.sh new file mode 100755 index 0000000..cdff6da --- /dev/null +++ b/install/protobuf/asset_cpp/clean.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bazel clean --expunge diff --git a/install/protobuf/asset_cpp/client/BUILD.tpl b/install/protobuf/asset_cpp/client/BUILD.tpl new file mode 100644 index 0000000..ac81a98 --- /dev/null +++ b/install/protobuf/asset_cpp/client/BUILD.tpl @@ -0,0 +1,35 @@ +cc_binary( + name = "future_client", + srcs = ["future_client.cc"], + deps = [ + {{- if eq (dir .RelatvieFilePath) "." }} + "@proto//:{{ basenamewithoutext .FilePath | lower }}_proto", + {{- else }} + "@proto//:{{ (join (splitList "/" (dir .RelatvieFilePath )) "_") }}_{{ basenamewithoutext .FilePath | lower }}_proto", + {{- end }} + "@trpc_cpp//trpc/client:make_client_context", + "@trpc_cpp//trpc/client:trpc_client", + "@trpc_cpp//trpc/common:runtime_manager", + "@trpc_cpp//trpc/log:trpc_log", + "@trpc_cpp//trpc/util/thread:latch", + "@com_github_gflags_gflags//:gflags", + ], +) + +cc_binary( + name = "fiber_client", + srcs = ["fiber_client.cc"], + deps = [ + {{- if eq (dir .RelatvieFilePath) "." }} + "@proto//:{{ basenamewithoutext .FilePath | lower }}_proto", + {{- else }} + "@proto//:{{ (join (splitList "/" (dir .RelatvieFilePath )) "_") }}_{{ basenamewithoutext .FilePath | lower }}_proto", + {{- end }} + "@trpc_cpp//trpc/client:make_client_context", + "@trpc_cpp//trpc/client:trpc_client", + "@trpc_cpp//trpc/common/config:trpc_config", + "@trpc_cpp//trpc/common:runtime_manager", + "@trpc_cpp//trpc/log:trpc_log", + "@com_github_gflags_gflags//:gflags", + ], +) diff --git a/install/protobuf/asset_cpp/client/conf/trpc_cpp_fiber.yaml.tpl b/install/protobuf/asset_cpp/client/conf/trpc_cpp_fiber.yaml.tpl new file mode 100644 index 0000000..8edcb61 --- /dev/null +++ b/install/protobuf/asset_cpp/client/conf/trpc_cpp_fiber.yaml.tpl @@ -0,0 +1,25 @@ +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +global: + threadmodel: + fiber: + - instance_name: fiber_instance + concurrency_hint: 8 + +client: + service: + {{- range $idx, $svc := .Services }} + - name: trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }} + target: 127.0.0.1:5432{{ $idx }} + protocol: trpc + network: tcp + selector_name: direct + {{- end }} + +plugins: + log: + default: + - name: default + sinks: + local_file: + filename: trpc_fiber_client.log \ No newline at end of file diff --git a/install/protobuf/asset_cpp/client/conf/trpc_cpp_future.yaml.tpl b/install/protobuf/asset_cpp/client/conf/trpc_cpp_future.yaml.tpl new file mode 100644 index 0000000..d7077e6 --- /dev/null +++ b/install/protobuf/asset_cpp/client/conf/trpc_cpp_future.yaml.tpl @@ -0,0 +1,27 @@ +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +global: + threadmodel: + default: + - instance_name: default_instance + io_handle_type: separate + io_thread_num: 2 + handle_thread_num: 6 + +client: + service: + {{- range $idx, $svc := .Services }} + - name: trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }} + target: 127.0.0.1:5432{{ $idx }} + protocol: trpc + network: tcp + selector_name: direct + {{- end }} + +plugins: + log: + default: + - name: default + sinks: + local_file: + filename: trpc_client.log \ No newline at end of file diff --git a/install/protobuf/asset_cpp/client/fiber_client.cc.tpl b/install/protobuf/asset_cpp/client/fiber_client.cc.tpl new file mode 100644 index 0000000..66bfa39 --- /dev/null +++ b/install/protobuf/asset_cpp/client/fiber_client.cc.tpl @@ -0,0 +1,104 @@ +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +{{- $pkgNamespace := (replace .PackageName "." "::") -}} +#include +#include + +#include "gflags/gflags.h" + +#include "trpc/client/make_client_context.h" +#include "trpc/client/trpc_client.h" +#include "trpc/common/runtime_manager.h" +#include "trpc/log/trpc_log.h" + +#include "{{ trimright ".proto" .RelatvieFilePath }}.trpc.pb.h" + +DEFINE_string(client_config, "trpc_cpp.yaml", "framework client config file, --client_config=trpc_cpp.yaml"); +{{- range $idx, $svc := .Services -}} +{{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} +DEFINE_string(service_name{{ $idx_suffix }}, "trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }}", "callee service name"); +{{- end }} + +{{ range $idx, $svc := .Services }} +{{ range $method := .RPC }} +{{- $rpcReqType := (replace $method.RequestType "." "::") -}} +{{- $rpcRspType := (replace $method.ResponseType "." "::") -}} +int {{ $svc.Name }}{{ $method.Name }}(const std::shared_ptr<::{{ $pkgNamespace }}::{{ $svc.Name }}ServiceProxy>& proxy) { + {{- if and $method.ClientStreaming $method.ServerStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_stream in trpc-cpp project + return 0; + {{- else if $method.ClientStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_stream in trpc-cpp project + return 0; + {{- else if $method.ServerStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_stream in trpc-cpp project + return 0; + {{- else }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + ::{{ $rpcReqType }} req; + // fill some filed of req + ::{{ $rpcRspType }} rsp; + ::trpc::Status status = proxy->{{ $method.Name }}(client_ctx, req, &rsp); + if (!status.OK()) { + std::cerr << "get rpc error: " << status.ErrorMessage() << std::endl; + return -1; + } + std::cout << "get rsp success" << std::endl; + return 0; + {{- end }} +} + +{{ end -}} +{{ end -}} +int Run() { + {{- $svc0 := (index .Services 0) -}} + {{- if and (eq (len .Services) 1) (eq (len $svc0.RPC) 1) -}} + {{- $method := (index $svc0.RPC 0) }} + auto proxy = ::trpc::GetTrpcClient()->GetProxy<::{{ $pkgNamespace }}::{{ $svc0.Name }}ServiceProxy>(FLAGS_service_name); + return {{ $svc0.Name }}{{ $method.Name }}(proxy); + {{- else }} + int ret = 0; + {{ range $idx, $svc := .Services }} + {{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} + auto proxy{{ $idx_suffix }} = ::trpc::GetTrpcClient()->GetProxy<::{{ $pkgNamespace }}::{{ $svc.Name }}ServiceProxy>(FLAGS_service_name{{ $idx_suffix }}); + {{ range $method := .RPC -}} + ret = {{ $svc.Name }}{{ $method.Name }}(proxy{{ $idx_suffix }}); + if (ret < 0) return ret; + {{ end -}} + {{ end }} + return ret; + {{- end }} +} + +void ParseClientConfig(int argc, char* argv[]) { + google::ParseCommandLineFlags(&argc, &argv, true); + google::CommandLineFlagInfo info; + if (GetCommandLineFlagInfo("client_config", &info) && info.is_default) { + TRPC_FMT_ERROR("start client with config, for example:{} --client_config=/client/config/filepath", argv[0]); + exit(-1); + } + {{ range $idx, $svc := .Services -}} + {{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} + std::cout << "FLAGS_service_name{{ $idx_suffix }}: " << FLAGS_service_name{{ $idx_suffix }} << std::endl; + {{- end }} + std::cout << "FLAGS_client_config: " << FLAGS_client_config << std::endl; + + int ret = ::trpc::TrpcConfig::GetInstance()->Init(FLAGS_client_config); + if (ret != 0) { + std::cerr << "load client_config failed." << std::endl; + exit(-1); + } +} + +int main(int argc, char* argv[]) { + ParseClientConfig(argc, argv); + // If the business code is running in trpc pure client mode, + // the business code needs to be running in the `RunInTrpcRuntime` function + // This function can be seen as a program entry point and should be called only once. + return ::trpc::RunInTrpcRuntime([]() { + return Run(); + }); +} diff --git a/install/protobuf/asset_cpp/client/future_client.cc.tpl b/install/protobuf/asset_cpp/client/future_client.cc.tpl new file mode 100644 index 0000000..4d3f2e7 --- /dev/null +++ b/install/protobuf/asset_cpp/client/future_client.cc.tpl @@ -0,0 +1,115 @@ +{{- $pkgNamespace := (replace .PackageName "." "::") -}} +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +#include +#include + +#include "gflags/gflags.h" + +#include "trpc/client/make_client_context.h" +#include "trpc/client/trpc_client.h" +#include "trpc/common/runtime_manager.h" +#include "trpc/log/trpc_log.h" +#include "trpc/util/thread/latch.h" + +#include "{{ trimright ".proto" .RelatvieFilePath }}.trpc.pb.h" + +DEFINE_string(client_config, "trpc_cpp.yaml", "framework client config file, --client_config=trpc_cpp.yaml"); +{{- range $idx, $svc := .Services -}} +{{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} +DEFINE_string(service_name{{ $idx_suffix }}, "trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }}", "callee service name"); +{{- end }} + +{{ range $idx, $svc := .Services }} +{{ range $method := .RPC }} +{{- $rpcReqType := (replace $method.RequestType "." "::") -}} +{{- $rpcRspType := (replace $method.ResponseType "." "::") -}} +int {{ $svc.Name }}Async{{ $method.Name }}(const std::shared_ptr<::{{ $pkgNamespace }}::{{ $svc.Name }}ServiceProxy>& proxy) { + {{- if and $method.ClientStreaming $method.ServerStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_async_stream in trpc-cpp project + return 0; + {{- else if $method.ClientStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_async_stream in trpc-cpp project + return 0; + {{- else if $method.ServerStreaming }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + // Please refer to examples/features/trpc_async_stream in trpc-cpp project + return 0; + {{- else }} + ::trpc::ClientContextPtr client_ctx = ::trpc::MakeClientContext(proxy); + ::{{ $rpcReqType }} req; + // fill some filed of req + bool succ = true; + ::trpc::Latch latch(1); + proxy->Async{{ $method.Name }}(client_ctx, req). + Then([&latch, &succ](::trpc::Future<::{{ $rpcRspType }}>&& fut) { + if (fut.IsReady()) { + auto rsp = fut.GetValue0(); + // print some filed of rsp + std::cout << "get rsp success" << std::endl; + } else { + auto exception = fut.GetException(); + succ = false; + std::cerr << "get rpc error: " << exception.what() << std::endl; + } + latch.count_down(); + return ::trpc::MakeReadyFuture<>(); + }); + latch.wait(); + return succ ? 0 : -1; + {{- end }} +} + +{{ end -}} +{{ end }} +int Run() { + {{- $svc0 := (index .Services 0) -}} + {{- if and (eq (len .Services) 1) (eq (len $svc0.RPC) 1) -}} + {{- $method := (index $svc0.RPC 0) }} + auto proxy = ::trpc::GetTrpcClient()->GetProxy<::{{ $pkgNamespace }}::{{ $svc0.Name }}ServiceProxy>(FLAGS_service_name); + return {{ $svc0.Name }}Async{{ $method.Name }}(proxy); + {{- else }} + int ret = 0; + {{ range $idx, $svc := .Services }} + {{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} + auto proxy{{ $idx_suffix }} = ::trpc::GetTrpcClient()->GetProxy<::{{ $pkgNamespace }}::{{ $svc.Name }}ServiceProxy>(FLAGS_service_name{{ $idx_suffix }}); + {{ range $method := .RPC -}} + ret = {{ $svc.Name }}Async{{ $method.Name }}(proxy{{ $idx_suffix }}); + if (ret < 0) return ret; + {{ end -}} + {{ end }} + return ret; + {{- end }} +} + +void ParseClientConfig(int argc, char* argv[]) { + google::ParseCommandLineFlags(&argc, &argv, true); + google::CommandLineFlagInfo info; + if (GetCommandLineFlagInfo("client_config", &info) && info.is_default) { + TRPC_FMT_ERROR("start client with config, for example:{} --client_config=/client/config/filepath", argv[0]); + exit(-1); + } + {{ range $idx, $svc := .Services -}} + {{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} + std::cout << "FLAGS_service_name{{ $idx_suffix }}: " << FLAGS_service_name{{ $idx_suffix }} << std::endl; + {{- end }} + std::cout << "FLAGS_client_config: " << FLAGS_client_config << std::endl; + + int ret = ::trpc::TrpcConfig::GetInstance()->Init(FLAGS_client_config); + if (ret != 0) { + std::cerr << "load client_config failed." << std::endl; + exit(-1); + } +} + +int main(int argc, char* argv[]) { + ParseClientConfig(argc, argv); + // If the business code is running in trpc pure client mode, + // the business code needs to be running in the `RunInTrpcRuntime` function + // This function can be seen as a program entry point and should be called only once. + return ::trpc::RunInTrpcRuntime([]() { + return Run(); + }); +} diff --git a/install/protobuf/asset_cpp/proto/BUILD.tpl b/install/protobuf/asset_cpp/proto/BUILD.tpl new file mode 100644 index 0000000..98a06d8 --- /dev/null +++ b/install/protobuf/asset_cpp/proto/BUILD.tpl @@ -0,0 +1,27 @@ +package(default_visibility = ["//visibility:public"]) + +load("@trpc_cpp//trpc:trpc.bzl", "trpc_proto_library") +{{ range $pb, $deps := .Pb2DepsPbs -}} +{{- $depsCount := (len $deps) }} +trpc_proto_library( + {{ if eq (dir $pb ) "." -}} + name = "{{ basenamewithoutext $pb | lower }}_proto", + {{ else -}} + name = "{{ (join (splitList "/" (dir $pb )) "_") }}_{{ basenamewithoutext $pb | lower }}_proto", + {{ end -}} + srcs = ["{{ $pb }}"], + rootpath = "@trpc_cpp", + use_trpc_plugin = True, + {{- if ne $depsCount 0 }} + deps = [ + {{- range $dep := $deps }} + {{ if eq (dir $dep ) "." -}} + ":{{ basenamewithoutext $dep | lower }}_proto", + {{- else -}} + ":{{ (join (splitList "/" (dir $dep )) "_") }}_{{ basenamewithoutext $dep | lower }}_proto", + {{- end }} + {{- end }} + ], + {{- end }} +) +{{ end }} \ No newline at end of file diff --git a/install/protobuf/asset_cpp/proto/WORKSPACE b/install/protobuf/asset_cpp/proto/WORKSPACE new file mode 100644 index 0000000..e69de29 diff --git a/install/protobuf/asset_cpp/run_client.sh b/install/protobuf/asset_cpp/run_client.sh new file mode 100644 index 0000000..721bb71 --- /dev/null +++ b/install/protobuf/asset_cpp/run_client.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +bazel build //client/... +bazel-bin/client/fiber_client --client_config=client/conf/trpc_cpp_fiber.yaml +bazel-bin/client/future_client --client_config=client/conf/trpc_cpp_future.yaml diff --git a/install/protobuf/asset_cpp/run_server.sh b/install/protobuf/asset_cpp/run_server.sh new file mode 100755 index 0000000..cf01bbb --- /dev/null +++ b/install/protobuf/asset_cpp/run_server.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +bazel build //server/... +bazel-bin/server/server_bin --config=server/conf/trpc_cpp_fiber.yaml +# bazel-bin/server/server_bin --config=server/conf/trpc_cpp.yaml diff --git a/install/protobuf/asset_cpp/server/BUILD.tpl b/install/protobuf/asset_cpp/server/BUILD.tpl new file mode 100644 index 0000000..ed066cf --- /dev/null +++ b/install/protobuf/asset_cpp/server/BUILD.tpl @@ -0,0 +1,32 @@ +cc_binary( + name = "server_bin", + deps = [ + ":server", + ], +) + +cc_library( + name = "server", + srcs = ["server.cc"], + hdrs = ["server.h"], + deps = [ + ":service", + "@com_github_fmtlib_fmt//:fmtlib", + "@trpc_cpp//trpc/common:trpc_app", + "@trpc_cpp//trpc/log:trpc_log", + ], +) + +cc_library( + name = "service", + srcs = ["service.cc"], + hdrs = ["service.h"], + deps = [ + {{- if eq (dir .RelatvieFilePath) "." }} + "@proto//:{{ basenamewithoutext .FilePath | lower }}_proto", + {{- else }} + "@proto//:{{ (join (splitList "/" (dir .RelatvieFilePath )) "_") }}_{{ basenamewithoutext .FilePath | lower }}_proto", + {{- end }} + "@trpc_cpp//trpc/log:trpc_log", + ], +) diff --git a/install/protobuf/asset_cpp/server/conf/trpc_cpp.yaml.tpl b/install/protobuf/asset_cpp/server/conf/trpc_cpp.yaml.tpl new file mode 100644 index 0000000..3aa3c61 --- /dev/null +++ b/install/protobuf/asset_cpp/server/conf/trpc_cpp.yaml.tpl @@ -0,0 +1,31 @@ +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +global: + threadmodel: + default: + - instance_name: default_instance + io_handle_type: separate + io_thread_num: 2 + handle_thread_num: 6 + +server: + app: {{ $app }} + server: {{ $server }} + admin_port: 6666 + admin_ip: 0.0.0.0 + service: + {{- range $idx, $svc := .Services }} + - name: trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }} + protocol: trpc + network: tcp + ip: 0.0.0.0 + port: 5432{{ $idx }} + {{- end }} + +plugins: + log: + default: + - name: default + sinks: + local_file: + filename: trpc_server.log \ No newline at end of file diff --git a/install/protobuf/asset_cpp/server/conf/trpc_cpp_fiber.yaml.tpl b/install/protobuf/asset_cpp/server/conf/trpc_cpp_fiber.yaml.tpl new file mode 100644 index 0000000..1dd78d8 --- /dev/null +++ b/install/protobuf/asset_cpp/server/conf/trpc_cpp_fiber.yaml.tpl @@ -0,0 +1,29 @@ +{{- $app := .AppName -}} {{- if eq (len .AppName) 0 -}} {{- $app = "appdemo" -}} {{- end -}} +{{- $server := .ServerName -}} {{- if eq (len .ServerName) 0 -}} {{- $server = "serverdemo" -}} {{- end -}} +global: + threadmodel: + fiber: + - instance_name: fiber_instance + concurrency_hint: 8 + +server: + app: {{ $app }} + server: {{ $server }} + admin_port: 6666 + admin_ip: 0.0.0.0 + service: + {{- range $idx, $svc := .Services }} + - name: trpc.{{ $app }}.{{ $server }}.{{ $svc.Name }} + protocol: trpc + network: tcp + ip: 0.0.0.0 + port: 5432{{ $idx }} + {{- end }} + +plugins: + log: + default: + - name: default + sinks: + local_file: + filename: trpc_fiber_server.log \ No newline at end of file diff --git a/install/protobuf/asset_cpp/server/server.cc.tpl b/install/protobuf/asset_cpp/server/server.cc.tpl new file mode 100644 index 0000000..19aa997 --- /dev/null +++ b/install/protobuf/asset_cpp/server/server.cc.tpl @@ -0,0 +1,48 @@ +{{- $serverName := (basenamewithoutext .FilePath | camelcase) -}} +{{- $namespaces := (splitList "." .PackageName) -}} +{{- $reverseNamespaces := (splitList "." .PackageName | reverse) -}} +{{- $pkgNamespace := (replace .PackageName "." "::") -}} +#include "server/server.h" + +#include +#include + +#include "fmt/format.h" + +#include "trpc/log/trpc_log.h" + +#include "server/service.h" + +{{ range $val := $namespaces -}} +namespace {{ $val }} { +{{ end }} +// The initialization logic depending on framework runtime(threadmodel,transport,etc) or plugins(config,metrics,etc) should be placed here. +// Others can simply place at main function(before Main() function invoked) +int {{ $serverName }}Server::Initialize() { + const auto& config = ::trpc::TrpcConfig::GetInstance()->GetServerConfig(); + + // Set the service name, which must be the same as the value of the `/server/service/name` configuration item in the yaml file, + // otherwise the framework cannot receive requests normally. + {{- range $idx, $svc := .Services -}} + {{- $idx_suffix := $idx -}}{{- if (eq $idx 0) -}}{{- $idx_suffix = "" -}}{{- end }} + std::string service_name{{$idx_suffix}} = fmt::format("{}.{}.{}.{}", "trpc", config.app, config.server, "{{$svc.Name}}"); + ::trpc::ServicePtr my_service{{$idx_suffix}}(std::make_shared<{{$svc.Name}}ServiceImpl>()); + RegisterService(service_name{{$idx_suffix}}, my_service{{$idx_suffix}}); + TRPC_FMT_INFO("Register service: {}", service_name{{$idx_suffix}}); + {{ end }} + return 0; +} + +// If the resources initialized in the initialize function need to be destructed when the program exits, it is recommended to place them here. +void {{ $serverName }}Server::Destroy() {} + +{{ range $val := $reverseNamespaces -}} +} // namespace {{ $val }} +{{ end }} +int main(int argc, char** argv) { + ::{{ $pkgNamespace }}::{{ $serverName }}Server {{ $serverName | lower }}_server; + {{ $serverName | lower }}_server.Main(argc, argv); + {{ $serverName | lower }}_server.Wait(); + + return 0; +} diff --git a/install/protobuf/asset_cpp/server/server.h.tpl b/install/protobuf/asset_cpp/server/server.h.tpl new file mode 100644 index 0000000..e7cdc96 --- /dev/null +++ b/install/protobuf/asset_cpp/server/server.h.tpl @@ -0,0 +1,19 @@ +{{- $namespaces := (splitList "." .PackageName) -}} +{{- $reverseNamespaces := (splitList "." .PackageName | reverse) -}} +#pragma once + +#include "trpc/common/trpc_app.h" + +{{ range $val := $namespaces -}} +namespace {{ $val }} { +{{ end }} +class {{ basenamewithoutext .FilePath | camelcase }}Server : public ::trpc::TrpcApp { + public: + int Initialize() override; + + void Destroy() override; +}; + +{{ range $val := $reverseNamespaces -}} +} // namespace {{ $val }} +{{ end -}} diff --git a/install/protobuf/asset_cpp/server/service.cc.tpl b/install/protobuf/asset_cpp/server/service.cc.tpl new file mode 100644 index 0000000..0770292 --- /dev/null +++ b/install/protobuf/asset_cpp/server/service.cc.tpl @@ -0,0 +1,41 @@ +{{- $namespaces := (splitList "." .PackageName) -}} +{{- $reverseNamespaces := (splitList "." .PackageName | reverse) -}} +{{- $pkgNamespace := (replace .PackageName "." "::") -}} +#include "server/service.h" + +#include "trpc/log/trpc_log.h" + +{{ range $val := $namespaces -}} +namespace {{ $val }} { +{{ end }} +{{- range $svc := .Services }} +{{- range $method := .RPC -}} +{{- $rpcReqType := (replace $method.RequestType "." "::") -}} +{{- $rpcRspType := (replace $method.ResponseType "." "::") -}} +{{ if and $method.ClientStreaming $method.ServerStreaming }} +::trpc::Status {{ $svc.Name }}ServiceImpl::{{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::trpc::stream::StreamReader<::{{ $rpcReqType }}>& reader, ::trpc::stream::StreamWriter<::{{ $rpcRspType }}>* writer) { + // Please refer to examples/features/trpc_stream in trpc-cpp project + return ::trpc::kSuccStatus; +} +{{ else if $method.ClientStreaming }} +::trpc::Status {{ $svc.Name }}ServiceImpl::{{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::trpc::stream::StreamReader<::{{ $rpcReqType }}>& reader, ::{{ $rpcRspType }}* response) { + // Please refer to examples/features/trpc_stream in trpc-cpp project + return ::trpc::kSuccStatus; +} +{{ else if $method.ServerStreaming }} +::trpc::Status {{ $svc.Name }}ServiceImpl::{{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::{{ $rpcReqType }}& request, ::trpc::stream::StreamWriter<::{{ $rpcRspType }}>* writer) { + // Please refer to examples/features/trpc_stream in trpc-cpp project + return ::trpc::kSuccStatus; +} +{{ else }} +::trpc::Status {{ $svc.Name }}ServiceImpl::{{ $method.Name }}(::trpc::ServerContextPtr context, const ::{{ $rpcReqType }}* request, ::{{ $rpcRspType }}* reply) { + // Implement business logic here + TRPC_FMT_INFO("got req"); + return ::trpc::kSuccStatus; +} +{{ end }} +{{- end -}} +{{ end }} +{{ range $val := $reverseNamespaces -}} +} // namespace {{ $val }} +{{ end -}} diff --git a/install/protobuf/asset_cpp/server/service.h.tpl b/install/protobuf/asset_cpp/server/service.h.tpl new file mode 100644 index 0000000..24557d7 --- /dev/null +++ b/install/protobuf/asset_cpp/server/service.h.tpl @@ -0,0 +1,31 @@ +{{- $namespaces := (splitList "." .PackageName) -}} +{{- $reverseNamespaces := (splitList "." .PackageName | reverse) -}} +{{- $pkgNamespace := (replace .PackageName "." "::") -}} +#pragma once + +#include "{{ trimright ".proto" .RelatvieFilePath }}.trpc.pb.h" + +{{ range $val := $namespaces -}} +namespace {{ $val }} { +{{ end }} +{{- range $svc := .Services }} +class {{ $svc.Name }}ServiceImpl : public ::{{ $pkgNamespace }}::{{ $svc.Name }} { + public: + {{- range $method := .RPC -}} + {{- $rpcReqType := (replace $method.RequestType "." "::") -}} + {{- $rpcRspType := (replace $method.ResponseType "." "::") -}} + {{ if and $method.ClientStreaming $method.ServerStreaming }} + ::trpc::Status {{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::trpc::stream::StreamReader<::{{ $rpcReqType }}>& reader, ::trpc::stream::StreamWriter<::{{ $rpcRspType }}>* writer) override; + {{- else if $method.ClientStreaming }} + ::trpc::Status {{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::trpc::stream::StreamReader<::{{ $rpcReqType }}>& reader, ::{{ $rpcRspType }}* response) override; + {{- else if $method.ServerStreaming }} + ::trpc::Status {{ $method.Name }}(const ::trpc::ServerContextPtr& context, const ::{{ $rpcReqType }}& request, ::trpc::stream::StreamWriter<::{{ $rpcRspType }}>* writer) override; + {{- else }} + ::trpc::Status {{ $method.Name }}(::trpc::ServerContextPtr context, const ::{{ $rpcReqType }}* request, ::{{ $rpcRspType }}* reply) override; + {{- end -}} + {{ end }} +}; +{{ end }} +{{ range $val := $reverseNamespaces -}} +} // namespace {{ $val }} +{{ end -}} diff --git a/install/protobuf/asset_go/cmd/client/main.go.tpl b/install/protobuf/asset_go/cmd/client/main.go.tpl new file mode 100644 index 0000000..e80b04b --- /dev/null +++ b/install/protobuf/asset_go/cmd/client/main.go.tpl @@ -0,0 +1,144 @@ +// Package main is originally generated by trpc-cmdline {{ .TRPCCmdlineVersion }}. +// It is located at `project/cmd/client`. +// Run this file by executing `go run cmd/client/main.go` in the project directory. +package main + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} +{{- $sevriceProtocol := .Protocol -}} +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgName = . -}} +{{- end -}} +import ( + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/client" + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + _ "{{ $domainName }}/{{ $groupName }}/trpc-filter/debuglog{{ $versionSuffix }}" + pb "{{ trimright ";" $goPkgName }}" + {{ range $.ImportsX }} + {{.Name}} "{{.Path}}" + {{ end }} +) +{{- range $index, $service := .Services -}} +{{- $svrNameCamelCase := $service.Name | camelcase -}} +{{- range $mindex, $method := $service.RPC -}} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "pb.%s" (splitList "." $rpcReqType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltype $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "pb.%s" (splitList "." $rpcRspType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltype $rpcRspType $.FileDescriptor) -}} +{{- end }} + +func call{{$svrNameCamelCase}}{{$rpcName}}() { + proxy := pb.New{{$svrNameCamelCase}}ClientProxy( + client.WithTarget("ip://127.0.0.1:{{add 8000 $index}}"), + client.WithProtocol("{{$sevriceProtocol}}"), + ) + ctx := trpc.BackgroundContext() +{{- if and $method.ClientStreaming $method.ServerStreaming}} + // Example of using a bidirectional streaming client. + stream, err := proxy.{{$rpcName}}(ctx) + if err != nil { + log.Fatalf("err: %v", err) + } + for i := 0; i < 5; i++ { + if err := stream.Send(&{{$rpcReqType}}{}); err != nil { + log.Fatalf("err: %v", err) + } + } + if err := stream.CloseSend(); err != nil { + log.Fatalf("err: %v", err) + } + for { + rsp, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("err: %v", err) + } + log.Debugf(" bidi stream receive: %+v", rsp) + } +{{- else if $method.ClientStreaming}} + // Example usage of client-side streaming. + stream, err := proxy.{{$rpcName}}(ctx) + if err != nil { + log.Fatalf("err: %v", err) + } + for i := 0; i < 5; i++ { + if err := stream.Send(&{{$rpcReqType}}{}); err != nil { + log.Fatalf("err: %v", err) + } + } + rsp, err := stream.CloseAndRecv() + if err != nil { + log.Fatalf("err: %v", err) + } + log.Debugf("client stream receive: %+v", rsp) +{{- else if $method.ServerStreaming}} + // Example usage of server-side streaming. + stream, err := proxy.{{$rpcName}}(ctx, &{{$rpcReqType}}{}) + if err != nil { + log.Fatalf("err: %v", err) + } + for { + reply, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + log.Fatalf("err: %v", err) + } + log.Debugf("server stream receive: %+v", reply) + } +{{- else}} + // Example usage of unary client. + reply, err := proxy.{{$rpcName}}(ctx, &{{$rpcReqType}}{}) + if err != nil { + log.Fatalf("err: %v", err) + } + log.Debugf("simple rpc receive: %+v", reply) +{{- end}} +} +{{- end}} +{{- end}} + +func main() { + // Load configuration following the logic in trpc.NewServer. + cfg, err := trpc.LoadConfig(trpc.ServerConfigPath) + if err != nil { + panic("load config fail: " + err.Error()) + } + trpc.SetGlobalConfig(cfg) + if err := trpc.Setup(cfg); err != nil { + panic("setup plugin fail: " + err.Error()) + } +{{- range $index, $service := .Services -}} +{{- $svrNameCamelCase := $service.Name | camelcase -}} +{{- range $mindex, $method := $service.RPC -}} +{{- $rpcName := $method.Name | camelcase }} + call{{$svrNameCamelCase}}{{$rpcName}}() +{{- end}} +{{- end}} +} \ No newline at end of file diff --git a/install/protobuf/asset_go/go.mod.tpl b/install/protobuf/asset_go/go.mod.tpl new file mode 100644 index 0000000..f2dc5b0 --- /dev/null +++ b/install/protobuf/asset_go/go.mod.tpl @@ -0,0 +1,48 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} + + + +{{ $rpcdir := "" -}} +{{ if ne $goPkgOption "" -}} +{{ $rpcdir = $goPkgOption }} +{{- else -}} +{{ $rpcdir = $pkgName }} +{{- end -}} +replace {{$rpcdir}} => ./stub/{{$rpcdir}} + + +{{ range $k, $v := .Pb2ImportPath -}} +{{ $v = trimright ";" $v}} +{{ if and (not (hasprefix "trpc.tech/trpc-go/trpc/v2" $v)) + (not (hasprefix "trpc.group/trpc-go/trpc" $v)) + (not (hasprefix "trpc.group/trpc/trpc-protocol" $v)) + (not (hasprefix "trpc.group/wineguo/trpc-protocol" $v)) + (not (hasprefix "github.com/golang/protobuf" $v)) + (ne $v "trpc.group/devsec/protoc-gen-secv/v2/validate") + (ne $v "trpc.group/devsec/protoc-gen-secv/validate") + (not (hasprefix "google/protobuf/" $k)) }} +replace {{$v}} => ./stub/{{$v}} +{{ end }} + +{{ end }} + +{{ if ne $.TRPCGoVersion "" }} +require {{ $domainName }}/{{ $groupName }}/trpc-go {{.TRPCGoVersion}} +{{ end }} diff --git a/install/protobuf/asset_go/main.go.tpl b/install/protobuf/asset_go/main.go.tpl new file mode 100644 index 0000000..bd2abbb --- /dev/null +++ b/install/protobuf/asset_go/main.go.tpl @@ -0,0 +1,48 @@ +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} +{{- $serviceSuffix := "" -}} +{{- if not .NoServiceSuffix }} + {{- $serviceSuffix = "Service" }} +{{- end }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +package main + +import ( + {{- if secvtpl $.Pkg2ValidGoPkg }} + {{/* _ "{{$domainName}}/{{$groupName}}/trpc-filter/validation{{$versionSuffix}}" */}} + {{- end }} + _ "{{$domainName}}/{{$groupName}}/trpc-filter/debuglog{{$versionSuffix}}" + _ "{{$domainName}}/{{$groupName}}/trpc-filter/recovery{{$versionSuffix}}" + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + {{ if ne $goPkgOption "" -}} + pb "{{ trimright ";" $goPkgOption }}" + {{- else -}} + pb "{{$pkgName}}" + {{- end }} +) + +{{- $appName := .AppName -}} +{{- $serverName := .ServerName }} + +func main() { + s := trpc.NewServer() + {{range $index, $service := .Services}} + {{- $svrNameCamelCase := $service.Name | camelcase -}} + {{- $serviceName := $service.Name -}} + pb.Register{{$svrNameCamelCase}}{{$serviceSuffix}}(s.Service("{{- if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end -}}"), &{{$svrNameCamelCase|untitle}}Impl{}) + {{end -}} + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} diff --git a/install/protobuf/asset_go/rpc/go.mod.tpl b/install/protobuf/asset_go/rpc/go.mod.tpl new file mode 100644 index 0000000..0bc658c --- /dev/null +++ b/install/protobuf/asset_go/rpc/go.mod.tpl @@ -0,0 +1,20 @@ +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if ne $goPkgOption "" -}} +module {{trimright ";" $goPkgOption}} +{{- else -}} +module {{$pkgName}} +{{- end }} + +go {{.GoVersion}} + +{{ if ne $.TRPCGoVersion "" }} +require {{ $domainName }}/{{ $groupName }}/trpc-go {{.TRPCGoVersion}} +{{ end }} diff --git a/install/protobuf/asset_go/rpc/trpc.go.tpl b/install/protobuf/asset_go/rpc/trpc.go.tpl new file mode 100644 index 0000000..4369956 --- /dev/null +++ b/install/protobuf/asset_go/rpc/trpc.go.tpl @@ -0,0 +1,588 @@ +// Code generated by trpc-go/trpc-cmdline {{ .TRPCCmdlineVersion }}. DO NOT EDIT. +// source: {{.Protofile}} + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} +{{- $serviceSuffix := "" -}} +{{- if not .NoServiceSuffix }} + {{- $serviceSuffix = "Service" }} +{{- end }} + +{{ $pkgName := .PackageName -}} +{{ $goPkgName := .PackageName|gopkg -}} +{{ $appName := .AppName -}} +{{ $serverName := .ServerName -}} +{{ $protocol := .Protocol -}} +{{ $protofile := .Protofile -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} + {{- $goPkgName = (splitList "/" $goPkgOption)|last|gopkg -}} +{{- end -}} +{{- $importStream := false }} +{{- $existRESTfulHTTPRule := false }} +{{- range $service := .Services }} + {{- range $rpc := $service.RPC }} + {{- if ne (len .RESTfulAPIInfo.ContentList) 0 }} + {{- $existRESTfulHTTPRule = true}} + {{- end }} + {{- if or $rpc.ClientStreaming $rpc.ServerStreaming }} + {{- $importStream = true }} + {{- end }} + {{- end }} +{{- end }} +package {{ splitList ";" $goPkgName | last }} + +{{ $goPkgName = trimright ";" $goPkgName }} + +import ( + "context" + "fmt" + + _ "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}" + _ "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/http" + {{- if and (ne .Protocol "trpc") (ne .Protocol "http") (ne .Protocol "grpc") }} + _ "{{ $domainName }}/{{ $groupName }}/trpc-codec/{{.Protocol}}{{ $versionSuffix }}" + {{- end }} + {{- if (eq .Protocol "grpc") }} + "{{ $domainName }}/{{ $groupName }}/trpc-codec/{{.Protocol}}{{ $versionSuffix }}" + {{- end }} + {{- if $existRESTfulHTTPRule }} + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/restful" + {{- end }} + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/server" + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/client" + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/codec" + {{- if $importStream }} + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/stream" + {{- end }} + {{- if eq $protocol "grpc" }} + "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/filter" + {{- end }} + {{- range .ImportsX }} + {{- if ne $goPkgName .Path }} + {{.Name}} "{{.Path}}" + {{- end }} + {{- end }} +) + +// START ======================================= Server Service Definition ======================================= START + +{{ range $service := .Services }} +{{- $svrName := $service.Name -}} +{{- $svrNameCamelCase := $service.Name|camelcase -}} + +{{- $serviceStream := false }} +{{- range $rpc := $service.RPC }} +{{- if or $rpc.ClientStreaming $rpc.ServerStreaming }} +{{- $serviceStream = true }} +{{- end }} +{{- end }} + +// {{$svrNameCamelCase}}{{$serviceSuffix}} defines service. +type {{$svrNameCamelCase}}{{$serviceSuffix}} interface { + {{- range $rpc := $service.RPC -}} + {{- $rpcName := .Name | camelcase -}} + {{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{ with .LeadingComments }}// {{$rpcName}} {{.}}{{ end }} + {{- if $rpc.ClientStreaming }} + {{$rpcName}}({{$svrNameCamelCase}}_{{$rpcName}}Server) error {{ with .TrailingComments}}// {{.}}{{ end }} + {{- else }} + {{- if $rpc.ServerStreaming }} + {{$rpcName}}(*{{$rpcReqType}}, {{$svrNameCamelCase}}_{{$rpcName}}Server) error {{ with .TrailingComments}}// {{.}}{{ end }} + {{- else }} + {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}) (*{{$rpcRspType}}, error) {{ with .TrailingComments}}// {{.}}{{ end }} + {{- end }} + {{- end }} + {{- end }} +} + +{{range $service.RPC -}} +{{- $rpcName := .Name | camelcase -}} +{{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + +{{- if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} +func {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler(svr interface{}, ctx context.Context, f server.FilterFunc) (interface{}, error) { + req := &{{$rpcReqType}}{} + filters, err := f(req) + if err != nil { + return nil, err + } + handleFunc := func(ctx context.Context, reqbody interface{}) (interface{}, error) { + return svr.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(ctx, reqbody.(*{{$rpcReqType}})) + } + {{ if eq $protocol "grpc" }} + // get req from ctx + grpcData := ctx.Value(grpc.ContextKeyHeader).(*grpc.Header) + req = grpcData.Req.(*{{$rpcReqType}}) + {{ end }} + var rsp interface{} + rsp, err = filters.Filter(ctx, req, handleFunc) + if err != nil { + return nil, err + } + {{- if eq $protocol "grpc" }} + // Set rsp to ctx, and set rsp empty. + grpcData.Rsp = rsp + rsp = &{{$rpcRspType}}{} + {{- end }} + return rsp, nil +} +{{- else }} +func {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler(srv interface{}, stream server.Stream) error { + {{- if (ne .ClientStreaming true) }} + m := new({{$rpcReqType}}) + if err := stream.RecvMsg(m); err != nil { return err } + return srv.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(m, &{{$svrNameCamelCase|untitle}}{{$rpcName}}Server{stream}) + {{- else }} + return srv.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(&{{$svrNameCamelCase|untitle}}{{$rpcName}}Server{stream}) + {{- end }} +} +{{ $genSend := .ServerStreaming }} +{{- $genSendAndClose := not .ServerStreaming -}} +{{- $genRecv := .ClientStreaming -}} +type {{$svrNameCamelCase}}_{{$rpcName}}Server interface { + {{- if $genSend }} + Send(*{{$rpcRspType}}) error + {{- end }} + {{- if $genSendAndClose }} + SendAndClose(*{{$rpcRspType}}) error + {{- end }} + {{- if $genRecv }} + Recv() (*{{$rpcReqType}}, error) + {{- end }} + server.Stream +} + +type {{$svrNameCamelCase|untitle}}{{$rpcName}}Server struct { + server.Stream +} + +{{ if $genSend }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) Send(m *{{$rpcRspType}}) error { + return x.Stream.SendMsg(m) +} +{{ end }} + +{{ if $genSendAndClose }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) SendAndClose(m *{{$rpcRspType}}) error { + return x.Stream.SendMsg(m) +} +{{ end }} + +{{ if $genRecv }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Server) Recv() (*{{$rpcReqType}}, error) { + m := new({{$rpcReqType}}) + if err := x.Stream.RecvMsg(m); err != nil { return nil, err } + return m, nil +} +{{ end }} +{{- end }} +{{end -}} + +{{- range $service.RPC -}} +{{- $rpcName := .Name | camelcase }} +{{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + +{{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + +{{- range $index, $content := .RESTfulAPIInfo.ContentList -}} +{{- if $content.RequestBody}} +// requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} {{$content.Method}}: {{$content.PathTmpl}} +type requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} struct{} + +func (requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Locate(message restful.ProtoMessage) interface{} { + x := message.(*{{$rpcReqType}}) + {{- if eq $content.RequestBody "*"}} + return x + {{- else}} + return &x.{{camelcase $content.RequestBody}} + {{- end}} +} + +func (requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Body() string { + return "{{$content.RequestBody}}" +} +{{- end -}} + +{{- if $content.ResponseBody}} +// responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} {{$content.Method}}: {{$content.PathTmpl}} +type responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}} struct{} + +func (responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) Locate(message restful.ProtoMessage) interface{} { + x := message.(*{{$rpcRspType}}) + {{- if eq $content.ResponseBody "*"}} + return x + {{- else}} + return &x.{{camelcase $content.ResponseBody}} + {{- end}} +} + +func (responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}) ResponseBody() string { + return "{{$content.ResponseBody}}" +} + +{{end}} +{{end}} +{{end}} +{{end}} + +// {{$svrNameCamelCase}}Server_ServiceDesc descriptor for server.RegisterService. +var {{$svrNameCamelCase}}Server_ServiceDesc = server.ServiceDesc { + ServiceName: " + {{- if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$service.Name -}} + {{- else -}} + {{- $pkgName}}.{{$service.Name -}} + {{- end}}", + HandlerType: ((*{{$svrNameCamelCase}}{{$serviceSuffix}})(nil)), + {{- if $serviceStream }} + StreamHandle: stream.NewStreamDispatcher(), + {{- end }} + Methods: []server.Method{ + {{- range (mergerpc $service.RPC $service.RPCx) }} + {{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + {{- $rpcName := .Name | camelcase }} + { + Name: "{{.FullyQualifiedCmd}}", + Func: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + {{if .RESTfulAPIInfo.ContentList }} + {{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + + {{- $fullyQualifiedCmd := .FullyQualifiedCmd -}} + Bindings: []*restful.Binding{ + {{- range $index, $content := .RESTfulAPIInfo.ContentList -}} + { + Name: "{{$fullyQualifiedCmd}}", + Input: func() restful.ProtoMessage { return new({{$rpcReqType}}) }, + Filter: func(svc interface{}, ctx context.Context, reqbody interface{}) (interface{}, error) { + return svc.({{$svrNameCamelCase}}{{$serviceSuffix}}).{{$rpcName}}(ctx, reqbody.(*{{$rpcReqType}})) + }, + HTTPMethod: "{{$content.Method}}", + Pattern: restful.Enforce("{{$content.PathTmpl}}"), + Body: {{ if $content.RequestBody -}} + requestBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}{} + {{- else -}} + nil + {{- end}}, + ResponseBody: {{ if $content.ResponseBody -}} + responseBody{{$svrNameCamelCase}}{{$serviceSuffix}}{{$rpcName}}RESTfulPath{{$index}}{} + {{- else}} + nil + {{- end}}, + }, + {{- end -}} + }, + {{ end }} + }, + {{- end }} + {{- end}} + }, + {{- if $serviceStream }} + Streams: []server.StreamDesc{ + {{- range $service.RPC}} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $rpcName := .Name | camelcase }} + { + {{- if eq $protocol "trpc" }} + StreamName: "{{.FullyQualifiedCmd}}", + {{- end }} + {{- if eq $protocol "grpc" }} + StreamName: "{{$rpcName}}", + {{- end }} + Handler: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + ServerStreams: {{ .ServerStreaming }}, + }, + {{- end }} + {{- end }} + }, + {{- end }} +} + +// Register{{$svrNameCamelCase}}{{$serviceSuffix}} registers service. +func Register{{$svrNameCamelCase}}{{$serviceSuffix}}(s server.Service, svr {{$svrNameCamelCase}}{{$serviceSuffix}}) { + if err := s.Register(&{{$svrNameCamelCase}}Server_ServiceDesc, svr); err != nil { + panic(fmt.Sprintf("{{$svrNameCamelCase}} register error:%v", err)) + } + {{- if eq $protocol "grpc" }} + // register service to grpc + if err := grpc.Register({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName, + "{{$protofile}}", + []grpc.RegisterMethodsInfo{ + {{- range $service.RPC}} + {{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + + {{- if and (ne .ClientStreaming true ) (ne .ServerStreaming true ) }} + {{- $rpcName := .Name | camelcase }} + { + Method: server.Method{ + Name: "{{$rpcName}}", + Func: {{$svrNameCamelCase}}{{$serviceSuffix}}_{{$rpcName}}_Handler, + }, + ReqType: reflect.TypeOf({{$rpcReqType}}{}), + RspType: reflect.TypeOf({{$rpcRspType}}{}), + }, + {{- end }} + {{- end }} + }); err != nil { + panic(fmt.Sprintf("grpc register {{$svrNameCamelCase}} error:%v", err)) + } + if err := grpc.RegisterStream({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName, + "{{$protofile}}", + {{$svrNameCamelCase}}Server_ServiceDesc.Streams, + svr, (*{{$svrNameCamelCase}}{{$serviceSuffix}})(nil)); err != nil { + panic(fmt.Sprintf("grpc register {{$svrNameCamelCase}} streams error:%v", err)) + } + {{- end }} +} + +{{ end }} + +// START --------------------------------- Default Unimplemented Server Service --------------------------------- START + +{{ range $service := .Services }} +{{- $svrName := $service.Name | camelcase | untitle -}} +{{- $svrNameCamelCase := $service.Name|camelcase -}} +{{- $unimplementedName := (printf "Unimplemented%s" ($svrNameCamelCase)) -}} + +type {{$unimplementedName}} struct {} + +{{ range $index, $method := $service.RPC }} + +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := (simplify (gofulltypex $method.RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltypex $method.ResponseType $.FileDescriptor) $goPkgName)|export }} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{ with .LeadingComments }} +// {{$rpcName}} {{.}} +{{- end }} +{{- if and $method.ClientStreaming $method.ServerStreaming }} +func (s *{{$unimplementedName}}) {{$rpcName}}(stream {{$svrNameCamelCase}}_{{$rpcName}}Server) error { + return errors.New("rpc {{$rpcName}} of service {{$svrNameCamelCase}} is not implemented") +} +{{- else }} +{{- if $method.ClientStreaming }} +func (s *{{$unimplementedName}}) {{$rpcName}}(stream {{$svrNameCamelCase}}_{{$rpcName}}Server) error { + return errors.New("rpc {{$rpcName}} of service {{$svrNameCamelCase}} is not implemented") +} +{{- else }} +{{- if $method.ServerStreaming }} +func (s *{{$unimplementedName}}) {{$rpcName}}(req *{{$rpcReqType}}, stream {{$svrNameCamelCase}}_{{$rpcName}}Server) error { + return errors.New("rpc {{$rpcName}} of service {{$svrNameCamelCase}} is not implemented") +} +{{- else }} +func (s *{{$unimplementedName}}) {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}) (*{{$rpcRspType}}, error) { + return nil, errors.New("rpc {{$rpcName}} of service {{$svrNameCamelCase}} is not implemented") +} +{{- end }} +{{- end }} +{{- end }} + +{{- end }} +{{end}} + +// END --------------------------------- Default Unimplemented Server Service --------------------------------- END + +// END ======================================= Server Service Definition ======================================= END + +// START ======================================= Client Service Definition ======================================= START + +{{ range $service := .Services }} +{{ $svrNameCamelCase := $service.Name | camelcase }} + +// {{$svrNameCamelCase}}ClientProxy defines service client proxy +type {{$svrNameCamelCase}}ClientProxy interface { + {{- range $rpc := $service.RPC -}} + {{- $rpcName := .Name | camelcase -}} + {{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} + {{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + {{ with .LeadingComments }}// {{$rpcName}} {{.}}{{- end }} + {{- if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} + {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}, opts ...client.Option) (rsp *{{$rpcRspType}}, err error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- else }} + {{- if .ClientStreaming }} + {{$rpcName}}(ctx context.Context, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- else }} + {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) {{ with .TrailingComments }}// {{.}}{{ end }} + {{- end }} + {{- end }} + {{- end }} +} + +type {{$svrNameCamelCase}}ClientProxyImpl struct{ + client client.Client + {{- if $importStream }} + streamClient stream.Client + {{- end }} + opts []client.Option +} + +var New{{$svrNameCamelCase}}ClientProxy = func(opts...client.Option) {{$svrNameCamelCase}}ClientProxy { +{{- if $importStream }} + {{- if ne $protocol "grpc" }} + return &{{$svrNameCamelCase}}ClientProxyImpl {client: client.DefaultClient, streamClient: stream.DefaultStreamClient, opts: opts} + {{- else }} + return &{{$svrNameCamelCase}}ClientProxyImpl {client: client.DefaultClient, streamClient: grpc.DefaultStreamClient, opts: opts} + {{- end }} +{{- else }} + return &{{$svrNameCamelCase}}ClientProxyImpl {client: client.DefaultClient, opts: opts} +{{- end }} +} + +{{range $rpc := $service.RPC}} +{{- $rpcName := .Name | camelcase -}} +{{- $rpcReqType := (simplify (gofulltypex .RequestType $.FileDescriptor) $goPkgName)|export }} +{{- $rpcRspType := (simplify (gofulltypex .ResponseType $.FileDescriptor) $goPkgName)|export }} + +{{ if and (ne .ClientStreaming true) (ne .ServerStreaming true) }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}, opts ...client.Option) (*{{$rpcRspType}}, error) { + {{- if eq $protocol "grpc" }} + // set req to ctx + h := ctx.Value(grpc.ContextKeyHeader) + var header *grpc.Header + if h == nil { + header = &grpc.Header{} + ctx = context.WithValue(ctx, grpc.ContextKeyHeader, header) + } else { + var ok bool + header, ok = h.(*grpc.Header) + if !ok { + return nil, errors.New(fmt.Sprintf("grpc header in context cannot be transferred to grpc.Header")) + } + } + header.Req = req + header.Rsp = &{{$rpcRspType}}{} + {{- end }} + ctx, msg := codec.WithCloneMessage(ctx) + defer codec.PutBackMessage(msg) + msg.WithClientRPCName("{{.FullyQualifiedCmd}}") + msg.WithCalleeServiceName({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName) + msg.WithCalleeApp("{{$appName}}") + msg.WithCalleeServer("{{$serverName}}") + msg.WithCalleeService("{{$service.Name}}") + msg.WithCalleeMethod("{{$rpcName}}") + msg.WithSerializationType(codec.SerializationTypePB) + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + rsp := &{{$rpcRspType}}{} + {{- if eq $protocol "grpc" }} + callopts = append(callopts, client.WithProtocol("grpc")) + callopts = append(callopts, client.WithFilter(func(ctx context.Context, req1, rsp1 interface{}, next filter.ClientHandleFunc) error { + err := next(ctx, req1, rsp1) + header := ctx.Value(grpc.ContextKeyHeader).(*grpc.Header) + *rsp = *header.Rsp.(*{{$rpcRspType}}) + return err + })) + {{- end }} + if err := c.client.Invoke(ctx, req, rsp, callopts...); err != nil { + return nil, err + } + return rsp, nil +} +{{ else }} +{{- if .ClientStreaming }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) { +{{- else }} +func (c *{{$svrNameCamelCase}}ClientProxyImpl) {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}, opts ...client.Option) ({{$svrNameCamelCase}}_{{$rpcName}}Client, error) { +{{- end }} + ctx, msg := codec.WithCloneMessage(ctx) + + msg.WithClientRPCName("{{.FullyQualifiedCmd}}") + msg.WithCalleeServiceName({{$svrNameCamelCase}}Server_ServiceDesc.ServiceName) + msg.WithCalleeApp("{{$appName}}") + msg.WithCalleeServer("{{$serverName}}") + msg.WithCalleeService("{{$service.Name}}") + msg.WithCalleeMethod("{{$rpcName}}") + msg.WithSerializationType(codec.SerializationTypePB) + + clientStreamDesc := &client.ClientStreamDesc{} + {{- if eq $protocol "trpc" }} + clientStreamDesc.StreamName = "{{.FullyQualifiedCmd}}" + {{- end }} + {{- if eq $protocol "grpc" }} + clientStreamDesc.StreamName = "{{$rpcName}}" + {{- end }} + clientStreamDesc.ClientStreams = {{.ClientStreaming}} + clientStreamDesc.ServerStreams = {{.ServerStreaming}} + + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + + stream, err := c.streamClient.NewStream(ctx, clientStreamDesc, "{{.FullyQualifiedCmd}}", callopts...) + if err != nil { + return nil, err + } + x := &{{$svrNameCamelCase|untitle}}{{$rpcName}}Client{stream} + {{- if and (ne .ClientStreaming true) .ServerStreaming }} + if err := x.ClientStream.SendMsg(req); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + {{- end }} + return x, nil +} +{{ $genSend := .ClientStreaming }} +{{ $genRecv := .ServerStreaming }} +{{ $genCloseAndRecv := not .ServerStreaming }} +type {{$svrNameCamelCase}}_{{$rpcName}}Client interface { + {{- if $genSend }} + Send(*{{$rpcReqType}}) error + {{- end }} + {{- if $genRecv }} + Recv() (*{{$rpcRspType}}, error) + {{- end }} + {{- if $genCloseAndRecv }} + CloseAndRecv() (*{{$rpcRspType}}, error) + {{- end }} + client.ClientStream +} + +type {{$svrNameCamelCase|untitle}}{{$rpcName}}Client struct { + client.ClientStream +} +{{ if $genSend }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) Send(m *{{$rpcReqType}}) error { + return x.ClientStream.SendMsg(m) +} +{{ end }} +{{ if $genRecv}} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) Recv() (*{{$rpcRspType}}, error) { + m := new({{$rpcRspType}}) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} +{{ end }} +{{ if $genCloseAndRecv }} +func (x *{{$svrNameCamelCase|untitle}}{{$rpcName}}Client) CloseAndRecv() (*{{$rpcRspType}}, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new({{$rpcRspType}}) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} +{{ end }} +{{ end }} +{{ end }} +{{ end }} + +// END ======================================= Client Service Definition ======================================= END diff --git a/install/protobuf/asset_go/service_rpc.go.tpl b/install/protobuf/asset_go/service_rpc.go.tpl new file mode 100644 index 0000000..9a3eaed --- /dev/null +++ b/install/protobuf/asset_go/service_rpc.go.tpl @@ -0,0 +1,123 @@ +{{ $domainName := .Domain }} + +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgName = . -}} +{{- end -}} +package main + +import ( + "context" + {{- $importio := false }} + {{- range (index .Services .ServiceIndex).RPC }} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $importio = true }} + {{- end }} + {{- end }} + {{- if $importio }} + "io" + {{- end }} + + pb "{{ trimright ";" $goPkgName }}" + {{ range $.ImportsX }} + {{.Name}} "{{.Path}}" + {{ end }} +) + +{{/* Regardless of how the files are divided, .ServiceIndex is always valid */}} +{{ $service := (index .Services .ServiceIndex) -}} +{{- $svrName := $service.Name | camelcase | untitle -}} +{{- $svrNameCamelCase := $service.Name|camelcase -}} +{{- $unimplementedName := (printf "pb.Unimplemented%s" ($svrNameCamelCase)) -}} + +{{/* Regardless of how the files are divided, generate the Service type definition when .MethodIndex <= 0 */}} +{{- if le $.MethodIndex 0 }} +type {{$svrName}}Impl struct { + {{$unimplementedName}} +} +{{- end }} + +{{/* Execute this for the current loop, regardless of whether it is divided by method or the index value passed when dividing by method */}} +{{ range $index, $method := $service.RPC }} + +{{ if or (not $.PerMethod) (eq $.MethodIndex $index) }} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "pb.%s" (splitList "." $rpcReqType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltypex $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "pb.%s" (splitList "." $rpcRspType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltypex $rpcRspType $.FileDescriptor) -}} +{{- end -}} + +{{ with .LeadingComments }}// {{$rpcName}} {{.}}{{ end }} +{{- if and $method.ClientStreaming $method.ServerStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Bidirectional streaming scenario processing logic (for reference only, please modify as needed). + for { + _, err := stream.Recv() + if err == io.EOF { + return nil + } + if err != nil { + return err + } + err = stream.Send(&{{$rpcRspType}}{}) + if err != nil { + return err + } + } +} +{{- else }} +{{- if $method.ClientStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Client streaming scenario processing logic (for reference only, please modify as needed). + for { + _, err := stream.Recv() + if err == io.EOF { + return stream.SendAndClose(&{{$rpcRspType}}{}) + } + if err != nil { + return err + } + } +} +{{- else }} +{{- if $method.ServerStreaming }} +func (s *{{$svrName}}Impl) {{$rpcName}}(req *{{$rpcReqType}}, stream {{index (splitList "." $rpcReqType) 0}}.{{$svrNameCamelCase}}_{{$rpcName}}Server) error { + // Server streaming scenario processing logic (for reference only, please modify as needed). + for i := 0; i < 5; i++ { + err := stream.Send(&{{$rpcRspType}}{}) + if err != nil { + return err + } + } + return nil +} +{{- else }} +func (s *{{$svrName}}Impl) {{$rpcName}}(ctx context.Context, req *{{$rpcReqType}}) (*{{$rpcRspType}}, error) { + rsp := &{{$rpcRspType}}{} + return rsp, nil +} +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{end}} diff --git a/install/protobuf/asset_go/service_rpc_test.go.tpl b/install/protobuf/asset_go/service_rpc_test.go.tpl new file mode 100644 index 0000000..0b9c765 --- /dev/null +++ b/install/protobuf/asset_go/service_rpc_test.go.tpl @@ -0,0 +1,396 @@ +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} +{{- $serviceSuffix := "" -}} +{{- if not .NoServiceSuffix }} + {{- $serviceSuffix = "Service" }} +{{- end }} + +{{- $svrNameCamelCase := (index .Services .ServiceIndex).Name | camelcase -}} +{{- $goPkgName := .PackageName -}} +{{- with .FileOptions.go_package -}} +{{- $goPkgName = . -}} +{{- end -}} + +{{ $fname := (basenamewithoutext .FilePath) -}} +{{- $serviceIndex := .ServiceIndex -}} +{{ $service := (index .Services .ServiceIndex) -}} + +package main + +import ( + "context" + {{- $importio := false }} + {{- range (index .Services .ServiceIndex).RPC }} + {{- if or .ClientStreaming .ServerStreaming }} + {{- $importio = true }} + {{- end }} + {{- end }} + {{- if $importio }} + "io" + {{- end }} + "testing" + + trpc "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}" + _ "{{ $domainName }}/{{ $groupName }}/trpc-go{{ $versionSuffix }}/http" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + pb "{{ trimright ";" $goPkgName }}" + {{ range .ImportsX }} + {{.Name}} "{{.Path}}" + {{- end }} +) + +{{$svrName := $service.Name | camelcase | untitle}} +{{ $commaSeparated := (print ($svrName|title) "ClientProxy")}} + +{{- range (index .Services .ServiceIndex).RPC }} +{{- if or .ClientStreaming .ServerStreaming }} +{{- $rpcName := .Name | camelcase -}} + +{{- $commaSeparated = (print $commaSeparated "," $svrNameCamelCase "_" $rpcName "Client") }} +{{- $commaSeparated = (print $commaSeparated "," $svrNameCamelCase "_" $rpcName "Server") }} +{{- end }} +{{- end }} + +{{ $p1 := trimright ";" $goPkgName }} +{{ $p2 := splitList ";" $goPkgName | last | gopkg_simple }} + +//go:generate go mod tidy +//go:generate mockgen -destination=stub/{{$p1}}/{{$fname}}_mock.go -package={{$p2}} -self_package={{$p1}} --source=stub/{{$p1}}/{{$fname}}.trpc.go +{{range $index, $method := (index .Services .ServiceIndex).RPC}} +{{- $rpcName := $method.Name | camelcase -}} +{{- $rpcReqType := $method.RequestType -}} +{{- $rpcRspType := $method.ResponseType -}} + +{{- $reqTypePkg := $method.RequestTypePkgDirective -}} +{{- with $method.RequestTypeFileOptions.go_package -}} + {{- $reqTypePkg = . -}} +{{- end -}} + +{{- $rspTypePkg := $method.ResponseTypePkgDirective -}} +{{- with $method.ResponseTypeFileOptions.go_package -}} + {{- $rspTypePkg = . -}} +{{- end -}} + +{{- if (eq $reqTypePkg $goPkgName) -}} + {{- $rpcReqType = (printf "pb.%s" (splitList "." $rpcReqType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcReqType = (gofulltypex $rpcReqType $.FileDescriptor) -}} +{{- end -}} + +{{- if (eq $rspTypePkg $goPkgName) -}} + {{- $rpcRspType = (printf "pb.%s" (splitList "." $rpcRspType|last|export|camelcase)) -}} +{{- else -}} + {{- $rpcRspType = (gofulltypex $rpcRspType $.FileDescriptor) -}} +{{- end -}} + +{{- if and .ClientStreaming .ServerStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := pb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderClient := make([]*gomock.Call, 0) + inorderServer := make([]*gomock.Call, 0) + + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any()).AnyTimes() + + m.DoAndReturn(func(ctx context.Context, opts ...interface{}) (interface{}, error) { + + x := {{$rpcName|untitle}}Client.EXPECT().Send(gomock.Any()).AnyTimes() + + x.DoAndReturn(func(req interface{}) error { + + r, ok := req.(*{{$rpcReqType}}) + if !ok { + panic("invalid request") + } + + s := {{$rpcName|untitle}}Server.EXPECT().Recv().Return(r, nil) + inorderServer = append(inorderServer, s) + return nil + }) + + k := {{$rpcName|untitle}}Client.EXPECT().CloseSend() + + k.DoAndReturn(func() error { + + {{$rpcName|untitle}}Server.EXPECT().Recv().Return(nil, io.EOF) + + err := {{$svrName}}Service.{{$rpcName}}({{$rpcName|untitle}}Server) + if err != nil { + return err + } + + {{$rpcName|untitle}}Client.EXPECT().Recv().Return(nil, io.EOF) + return nil + }) + + return {{$rpcName|untitle}}Client, nil + }) + + gomock.InOrder(inorderServer...) + + s := {{$rpcName|untitle}}Server.EXPECT().Send(gomock.Any()).AnyTimes() + + s.DoAndReturn(func(rsp interface{}) error { + + r, ok := rsp.(*{{$rpcRspType}}) + if !ok { + panic("invalid response") + } + + c := {{$rpcName|untitle}}Client.EXPECT().Recv().Return(r, nil) + inorderClient = append(inorderClient, c) + return nil + }) + + gomock.InOrder(inorderClient...) + + // Start writing unit test logic (for reference only, please modify as needed). + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext()) + require.Nil(t, err) + require.NotNil(t, stream) + + for i := 0; i < 5; i++ { + + req := &{{$rpcReqType}}{} + + // Output each input parameter (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %v", req) + + err := stream.Send(req) + require.Nil(t, err) + } + + err = stream.CloseSend() + require.Nil(t, err) + + for { + rsp, err := stream.Recv() + if err == io.EOF { + break + } + + // Output each return value (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + + require.Nil(t, err) + } +} +{{ else }} +{{ if .ClientStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := pb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderServer := make([]*gomock.Call, 0) + + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any()).AnyTimes() + + m.DoAndReturn(func(ctx context.Context, opts ...interface{}) (interface{}, error) { + + x := {{$rpcName|untitle}}Client.EXPECT().Send(gomock.Any()).AnyTimes() + + x.DoAndReturn(func(req interface{}) error { + + r, ok := req.(*{{$rpcReqType}}) + if !ok { + panic("invalid request") + } + + s := {{$rpcName|untitle}}Server.EXPECT().Recv().Return(r, nil) + inorderServer = append(inorderServer, s) + return nil + }) + + k := {{$rpcName|untitle}}Client.EXPECT().CloseAndRecv() + + k.DoAndReturn(func() (interface{}, error) { + + rsp := &{{$rpcRspType}}{} + + {{$rpcName|untitle}}Server.EXPECT().Recv().Return(nil, io.EOF) + + s := {{$rpcName|untitle}}Server.EXPECT().SendAndClose(gomock.Any()) + + s.DoAndReturn(func(f interface{}) error { + + r, ok := f.(*{{$rpcRspType}}) + if !ok { + panic("invalid response") + } + + rsp = r + return nil + }) + + err := {{$svrName}}Service.{{$rpcName}}({{$rpcName|untitle}}Server) + if err != nil { + return nil, err + } + + return rsp, nil + }) + + return {{$rpcName|untitle}}Client, nil + }) + + gomock.InOrder(inorderServer...) + + // Start writing unit test logic (for reference only, please modify as needed). + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext()) + require.Nil(t, err) + require.NotNil(t, stream) + + for i := 0; i < 5; i++ { + + req := &{{$rpcReqType}}{} + + // Output each input parameter (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %v", req) + + err := stream.Send(req) + require.Nil(t, err) + } + + rsp, err := stream.CloseAndRecv() + + // Output the return value (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + + require.Nil(t, err) +} +{{ else }} +{{ if .ServerStreaming }} +func Test_{{$svrNameCamelCase}}_{{$rpcName}}(t *testing.T) { + var {{$svrName}}Service = &{{$svrName}}Impl{} + + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + {{$svrNameCamelCase|untitle}}ClientProxy := pb.NewMock{{$svrNameCamelCase}}ClientProxy(ctrl) + {{$rpcName|untitle}}Client := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Client(ctrl) + {{$rpcName|untitle}}Server := pb.NewMock{{$svrNameCamelCase}}_{{$rpcName}}Server(ctrl) + inorderClient := make([]*gomock.Call, 0) + + // Expected behavior. + m := {{$svrNameCamelCase|untitle}}ClientProxy.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() + + m.DoAndReturn(func(ctx context.Context, req interface{}, opts ...interface{}) (interface{}, error) { + + r, ok := req.(*{{$rpcReqType}}) + if !ok { + panic("invalid request") + } + + s := {{$rpcName|untitle}}Server.EXPECT().Send(gomock.Any()).AnyTimes() + + s.DoAndReturn(func(rsp interface{}) error { + + r, ok := rsp.(*{{$rpcRspType}}) + if !ok { + panic("invalid response") + } + + c := {{$rpcName|untitle}}Client.EXPECT().Recv().Return(r, nil) + inorderClient = append(inorderClient, c) + return nil + }) + + err := {{$svrName}}Service.{{$rpcName}}(r, {{$rpcName|untitle}}Server) + if err != nil { + return nil, err + } + + {{$rpcName|untitle}}Client.EXPECT().Recv().Return(nil, io.EOF) + + return {{$rpcName|untitle}}Client, nil + }) + + gomock.InOrder(inorderClient...) + + // Start writing unit test logic (for reference only, please modify as needed). + req := &{{$rpcReqType}}{} + + // Output the input parameters (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} req: %v", req) + + stream, err := {{$svrNameCamelCase|untitle}}ClientProxy.{{$rpcName}}(trpc.BackgroundContext(), req) + require.Nil(t, err) + require.NotNil(t, stream) + + for { + rsp, err := stream.Recv() + + if err == io.EOF { + break + } + + // Output each return value (check t.Logf output, run `go test -v`). + t.Logf("{{$svrNameCamelCase}}_{{$rpcName}} rsp: %v, err: %v", rsp, err) + + require.Nil(t, err) + } +} +{{ else }} +func Test_{{$svrNameCamelCase|untitle}}Impl_{{$rpcName}}(t *testing.T) { + {{- $svrName := $service.Name | camelcase | untitle}} + // Start writing mock logic. + ctrl := gomock.NewController(t) + defer ctrl.Finish() + {{$svrName}}Service := pb.NewMock{{$svrNameCamelCase}}{{$serviceSuffix}}(ctrl) + var inorderClient []*gomock.Call + // Expected behavior. + m := {{$svrName}}Service.EXPECT().{{$rpcName}}(gomock.Any(), gomock.Any()).AnyTimes() + m.DoAndReturn(func(ctx context.Context, req *{{$rpcReqType}}) (*{{$rpcRspType}}, error) { + s := &{{$svrName}}Impl{} + return s.{{$rpcName}}(ctx, req) + }) + gomock.InOrder(inorderClient...) + + // Start writing unit test logic. + type args struct { + ctx context.Context + req *{{$rpcReqType}} + rsp *{{$rpcRspType}} + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var rsp *{{$rpcRspType}} + var err error + if rsp, err = {{$svrName}}Service.{{$rpcName}}(tt.args.ctx, tt.args.req); (err != nil) != tt.wantErr { + t.Errorf("{{$svrNameCamelCase|untitle}}Impl.{{$rpcName}}() error = %v, wantErr %v", err, tt.wantErr) + } + if !reflect.DeepEqual(rsp, tt.args.rsp) { + t.Errorf("{{$svrNameCamelCase|untitle}}Impl.{{$rpcName}}() rsp got = %v, want %v", rsp, tt.args.rsp) + } + }) + } +} +{{ end }} +{{ end }} +{{- end }} +{{end}} diff --git a/install/protobuf/asset_go/trpc_go.yaml b/install/protobuf/asset_go/trpc_go.yaml new file mode 100644 index 0000000..aa7a3be --- /dev/null +++ b/install/protobuf/asset_go/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/install/protos/google/protobuf/any.proto b/install/protos/google/protobuf/any.proto new file mode 100644 index 0000000..6ed8a23 --- /dev/null +++ b/install/protos/google/protobuf/any.proto @@ -0,0 +1,158 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "AnyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Any` contains an arbitrary serialized protocol buffer message along with a +// URL that describes the type of the serialized message. +// +// Protobuf library provides support to pack/unpack Any values in the form +// of utility functions or additional generated methods of the Any type. +// +// Example 1: Pack and unpack a message in C++. +// +// Foo foo = ...; +// Any any; +// any.PackFrom(foo); +// ... +// if (any.UnpackTo(&foo)) { +// ... +// } +// +// Example 2: Pack and unpack a message in Java. +// +// Foo foo = ...; +// Any any = Any.pack(foo); +// ... +// if (any.is(Foo.class)) { +// foo = any.unpack(Foo.class); +// } +// +// Example 3: Pack and unpack a message in Python. +// +// foo = Foo(...) +// any = Any() +// any.Pack(foo) +// ... +// if any.Is(Foo.DESCRIPTOR): +// any.Unpack(foo) +// ... +// +// Example 4: Pack and unpack a message in Go +// +// foo := &pb.Foo{...} +// any, err := anypb.New(foo) +// if err != nil { +// ... +// } +// ... +// foo := &pb.Foo{} +// if err := any.UnmarshalTo(foo); err != nil { +// ... +// } +// +// The pack methods provided by protobuf library will by default use +// 'type.googleapis.com/full.type.name' as the type URL and the unpack +// methods only use the fully qualified type name after the last '/' +// in the type URL, for example "foo.bar.com/x/y.z" will yield type +// name "y.z". +// +// +// JSON +// ==== +// The JSON representation of an `Any` value uses the regular +// representation of the deserialized, embedded message, with an +// additional field `@type` which contains the type URL. Example: +// +// package google.profile; +// message Person { +// string first_name = 1; +// string last_name = 2; +// } +// +// { +// "@type": "type.googleapis.com/google.profile.Person", +// "firstName": , +// "lastName": +// } +// +// If the embedded message type is well-known and has a custom JSON +// representation, that representation will be embedded adding a field +// `value` which holds the custom JSON in addition to the `@type` +// field. Example (for message [google.protobuf.Duration][]): +// +// { +// "@type": "type.googleapis.com/google.protobuf.Duration", +// "value": "1.212s" +// } +// +message Any { + // A URL/resource name that uniquely identifies the type of the serialized + // protocol buffer message. This string must contain at least + // one "/" character. The last segment of the URL's path must represent + // the fully qualified name of the type (as in + // `path/google.protobuf.Duration`). The name should be in a canonical form + // (e.g., leading "." is not accepted). + // + // In practice, teams usually precompile into the binary all types that they + // expect it to use in the context of Any. However, for URLs which use the + // scheme `http`, `https`, or no scheme, one can optionally set up a type + // server that maps type URLs to message definitions as follows: + // + // * If no scheme is provided, `https` is assumed. + // * An HTTP GET on the URL must yield a [google.protobuf.Type][] + // value in binary format, or produce an error. + // * Applications are allowed to cache lookup results based on the + // URL, or have them precompiled into a binary to avoid any + // lookup. Therefore, binary compatibility needs to be preserved + // on changes to types. (Use versioned type names to manage + // breaking changes.) + // + // Note: this functionality is not currently available in the official + // protobuf release, and it is not used for type URLs beginning with + // type.googleapis.com. + // + // Schemes other than `http`, `https` (or the empty scheme) might be + // used with implementation specific semantics. + // + string type_url = 1; + + // Must be a valid serialized protocol buffer of the above specified type. + bytes value = 2; +} diff --git a/install/protos/google/protobuf/api.proto b/install/protos/google/protobuf/api.proto new file mode 100644 index 0000000..3d598fc --- /dev/null +++ b/install/protos/google/protobuf/api.proto @@ -0,0 +1,208 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/source_context.proto"; +import "google/protobuf/type.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "ApiProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/apipb"; + +// Api is a light-weight descriptor for an API Interface. +// +// Interfaces are also described as "protocol buffer services" in some contexts, +// such as by the "service" keyword in a .proto file, but they are different +// from API Services, which represent a concrete implementation of an interface +// as opposed to simply a description of methods and bindings. They are also +// sometimes simply referred to as "APIs" in other contexts, such as the name of +// this message itself. See https://cloud.google.com/apis/design/glossary for +// detailed terminology. +message Api { + // The fully qualified name of this interface, including package name + // followed by the interface's simple name. + string name = 1; + + // The methods of this interface, in unspecified order. + repeated Method methods = 2; + + // Any metadata attached to the interface. + repeated Option options = 3; + + // A version string for this interface. If specified, must have the form + // `major-version.minor-version`, as in `1.10`. If the minor version is + // omitted, it defaults to zero. If the entire version field is empty, the + // major version is derived from the package name, as outlined below. If the + // field is not empty, the version in the package name will be verified to be + // consistent with what is provided here. + // + // The versioning schema uses [semantic + // versioning](http://semver.org) where the major version number + // indicates a breaking change and the minor version an additive, + // non-breaking change. Both version numbers are signals to users + // what to expect from different versions, and should be carefully + // chosen based on the product plan. + // + // The major version is also reflected in the package name of the + // interface, which must end in `v`, as in + // `google.feature.v1`. For major versions 0 and 1, the suffix can + // be omitted. Zero major versions must only be used for + // experimental, non-GA interfaces. + // + // + string version = 4; + + // Source context for the protocol buffer service represented by this + // message. + SourceContext source_context = 5; + + // Included interfaces. See [Mixin][]. + repeated Mixin mixins = 6; + + // The source syntax of the service. + Syntax syntax = 7; +} + +// Method represents a method of an API interface. +message Method { + // The simple name of this method. + string name = 1; + + // A URL of the input message type. + string request_type_url = 2; + + // If true, the request is streamed. + bool request_streaming = 3; + + // The URL of the output message type. + string response_type_url = 4; + + // If true, the response is streamed. + bool response_streaming = 5; + + // Any metadata attached to the method. + repeated Option options = 6; + + // The source syntax of this method. + Syntax syntax = 7; +} + +// Declares an API Interface to be included in this interface. The including +// interface must redeclare all the methods from the included interface, but +// documentation and options are inherited as follows: +// +// - If after comment and whitespace stripping, the documentation +// string of the redeclared method is empty, it will be inherited +// from the original method. +// +// - Each annotation belonging to the service config (http, +// visibility) which is not set in the redeclared method will be +// inherited. +// +// - If an http annotation is inherited, the path pattern will be +// modified as follows. Any version prefix will be replaced by the +// version of the including interface plus the [root][] path if +// specified. +// +// Example of a simple mixin: +// +// package google.acl.v1; +// service AccessControl { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v1/{resource=**}:getAcl"; +// } +// } +// +// package google.storage.v2; +// service Storage { +// rpc GetAcl(GetAclRequest) returns (Acl); +// +// // Get a data record. +// rpc GetData(GetDataRequest) returns (Data) { +// option (google.api.http).get = "/v2/{resource=**}"; +// } +// } +// +// Example of a mixin configuration: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// +// The mixin construct implies that all methods in `AccessControl` are +// also declared with same name and request/response types in +// `Storage`. A documentation generator or annotation processor will +// see the effective `Storage.GetAcl` method after inheriting +// documentation and annotations as follows: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/{resource=**}:getAcl"; +// } +// ... +// } +// +// Note how the version in the path pattern changed from `v1` to `v2`. +// +// If the `root` field in the mixin is specified, it should be a +// relative path under which inherited HTTP paths are placed. Example: +// +// apis: +// - name: google.storage.v2.Storage +// mixins: +// - name: google.acl.v1.AccessControl +// root: acls +// +// This implies the following inherited HTTP annotation: +// +// service Storage { +// // Get the underlying ACL object. +// rpc GetAcl(GetAclRequest) returns (Acl) { +// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl"; +// } +// ... +// } +message Mixin { + // The fully qualified name of the interface which is included. + string name = 1; + + // If non-empty specifies a path under which inherited HTTP paths + // are rooted. + string root = 2; +} diff --git a/install/protos/google/protobuf/compiler/plugin.proto b/install/protos/google/protobuf/compiler/plugin.proto new file mode 100644 index 0000000..ef665d1 --- /dev/null +++ b/install/protos/google/protobuf/compiler/plugin.proto @@ -0,0 +1,183 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// +// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to +// change. +// +// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is +// just a program that reads a CodeGeneratorRequest from stdin and writes a +// CodeGeneratorResponse to stdout. +// +// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead +// of dealing with the raw protocol defined here. +// +// A plugin executable needs only to be placed somewhere in the path. The +// plugin should be named "protoc-gen-$NAME", and will then be used when the +// flag "--${NAME}_out" is passed to protoc. + +syntax = "proto2"; + +package google.protobuf.compiler; +option java_package = "com.google.protobuf.compiler"; +option java_outer_classname = "PluginProtos"; + +option go_package = "google.golang.org/protobuf/types/pluginpb"; + +import "google/protobuf/descriptor.proto"; + +// The version number of protocol compiler. +message Version { + optional int32 major = 1; + optional int32 minor = 2; + optional int32 patch = 3; + // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should + // be empty for mainline stable releases. + optional string suffix = 4; +} + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +message CodeGeneratorRequest { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + repeated string file_to_generate = 1; + + // The generator parameter passed on the command-line. + optional string parameter = 2; + + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. + repeated FileDescriptorProto proto_file = 15; + + // The version number of protocol compiler. + optional Version compiler_version = 3; + +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +message CodeGeneratorResponse { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparsable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + optional string error = 1; + + // A bitmask of supported features that the code generator supports. + // This is a bitwise "or" of values from the Feature enum. + optional uint64 supported_features = 2; + + // Sync with code_generator.h. + enum Feature { + FEATURE_NONE = 0; + FEATURE_PROTO3_OPTIONAL = 1; + } + + // Represents a single generated file. + message File { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + optional string name = 1; + + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + optional string insertion_point = 2; + + // The file contents. + optional string content = 15; + + // Information describing the file content being inserted. If an insertion + // point is used, this information will be appropriately offset and inserted + // into the code generation metadata for the generated files. + optional GeneratedCodeInfo generated_code_info = 16; + } + repeated File file = 15; +} diff --git a/install/protos/google/protobuf/descriptor.proto b/install/protos/google/protobuf/descriptor.proto new file mode 100644 index 0000000..156e410 --- /dev/null +++ b/install/protos/google/protobuf/descriptor.proto @@ -0,0 +1,911 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// The messages in this file describe the definitions found in .proto files. +// A valid .proto file can be translated directly to a FileDescriptorProto +// without any other information (e.g. without reading its imports). + + +syntax = "proto2"; + +package google.protobuf; + +option go_package = "google.golang.org/protobuf/types/descriptorpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.Protobuf.Reflection"; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// descriptor.proto must be optimized for speed because reflection-based +// algorithms don't work during bootstrapping. +option optimize_for = SPEED; + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +message FileDescriptorSet { + repeated FileDescriptorProto file = 1; +} + +// Describes a complete .proto file. +message FileDescriptorProto { + optional string name = 1; // file name, relative to root of source tree + optional string package = 2; // e.g. "foo", "foo.bar", etc. + + // Names of files imported by this file. + repeated string dependency = 3; + // Indexes of the public imported files in the dependency list above. + repeated int32 public_dependency = 10; + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + repeated int32 weak_dependency = 11; + + // All top-level definitions in this file. + repeated DescriptorProto message_type = 4; + repeated EnumDescriptorProto enum_type = 5; + repeated ServiceDescriptorProto service = 6; + repeated FieldDescriptorProto extension = 7; + + optional FileOptions options = 8; + + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + optional SourceCodeInfo source_code_info = 9; + + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + optional string syntax = 12; +} + +// Describes a message type. +message DescriptorProto { + optional string name = 1; + + repeated FieldDescriptorProto field = 2; + repeated FieldDescriptorProto extension = 6; + + repeated DescriptorProto nested_type = 3; + repeated EnumDescriptorProto enum_type = 4; + + message ExtensionRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + + optional ExtensionRangeOptions options = 3; + } + repeated ExtensionRange extension_range = 5; + + repeated OneofDescriptorProto oneof_decl = 8; + + optional MessageOptions options = 7; + + // Range of reserved tag numbers. Reserved tag numbers may not be used by + // fields or extension ranges in the same message. Reserved ranges may + // not overlap. + message ReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Exclusive. + } + repeated ReservedRange reserved_range = 9; + // Reserved field names, which may not be used by fields in the same message. + // A given name may only be reserved once. + repeated string reserved_name = 10; +} + +message ExtensionRangeOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +// Describes a field within a message. +message FieldDescriptorProto { + enum Type { + // 0 is reserved for errors. + // Order is weird for historical reasons. + TYPE_DOUBLE = 1; + TYPE_FLOAT = 2; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + TYPE_INT64 = 3; + TYPE_UINT64 = 4; + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + TYPE_INT32 = 5; + TYPE_FIXED64 = 6; + TYPE_FIXED32 = 7; + TYPE_BOOL = 8; + TYPE_STRING = 9; + // Tag-delimited aggregate. + // Group type is deprecated and not supported in proto3. However, Proto3 + // implementations should still be able to parse the group wire format and + // treat group fields as unknown fields. + TYPE_GROUP = 10; + TYPE_MESSAGE = 11; // Length-delimited aggregate. + + // New in version 2. + TYPE_BYTES = 12; + TYPE_UINT32 = 13; + TYPE_ENUM = 14; + TYPE_SFIXED32 = 15; + TYPE_SFIXED64 = 16; + TYPE_SINT32 = 17; // Uses ZigZag encoding. + TYPE_SINT64 = 18; // Uses ZigZag encoding. + } + + enum Label { + // 0 is reserved for errors + LABEL_OPTIONAL = 1; + LABEL_REQUIRED = 2; + LABEL_REPEATED = 3; + } + + optional string name = 1; + optional int32 number = 3; + optional Label label = 4; + + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + optional Type type = 5; + + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + optional string type_name = 6; + + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + optional string extendee = 2; + + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + optional string default_value = 7; + + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. + optional int32 oneof_index = 9; + + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + optional string json_name = 10; + + optional FieldOptions options = 8; + + // If true, this is a proto3 "optional". When a proto3 field is optional, it + // tracks presence regardless of field type. + // + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still + // indicates the semantic detail of whether the user wrote "optional" or not. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. + // + // Proto2 optional fields do not set this flag, because they already indicate + // optional with `LABEL_OPTIONAL`. + optional bool proto3_optional = 17; +} + +// Describes a oneof. +message OneofDescriptorProto { + optional string name = 1; + optional OneofOptions options = 2; +} + +// Describes an enum type. +message EnumDescriptorProto { + optional string name = 1; + + repeated EnumValueDescriptorProto value = 2; + + optional EnumOptions options = 3; + + // Range of reserved numeric values. Reserved values may not be used by + // entries in the same enum. Reserved ranges may not overlap. + // + // Note that this is distinct from DescriptorProto.ReservedRange in that it + // is inclusive such that it can appropriately represent the entire int32 + // domain. + message EnumReservedRange { + optional int32 start = 1; // Inclusive. + optional int32 end = 2; // Inclusive. + } + + // Range of reserved numeric values. Reserved numeric values may not be used + // by enum values in the same enum declaration. Reserved ranges may not + // overlap. + repeated EnumReservedRange reserved_range = 4; + + // Reserved enum value names, which may not be reused. A given name may only + // be reserved once. + repeated string reserved_name = 5; +} + +// Describes a value within an enum. +message EnumValueDescriptorProto { + optional string name = 1; + optional int32 number = 2; + + optional EnumValueOptions options = 3; +} + +// Describes a service. +message ServiceDescriptorProto { + optional string name = 1; + repeated MethodDescriptorProto method = 2; + + optional ServiceOptions options = 3; +} + +// Describes a method of a service. +message MethodDescriptorProto { + optional string name = 1; + + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + optional string input_type = 2; + optional string output_type = 3; + + optional MethodOptions options = 4; + + // Identifies if client streams multiple client messages + optional bool client_streaming = 5 [default = false]; + // Identifies if server streams multiple server messages + optional bool server_streaming = 6 [default = false]; +} + + +// =================================================================== +// Options + +// Each of the definitions above may have "options" attached. These are +// just annotations which may cause code to be generated slightly differently +// or may contain hints for code that manipulates protocol messages. +// +// Clients may define custom options as extensions of the *Options messages. +// These extensions may not yet be known at parsing time, so the parser cannot +// store the values in them. Instead it stores them in a field in the *Options +// message called uninterpreted_option. This field must have the same name +// across all *Options messages. We then use this field to populate the +// extensions when we build a descriptor, at which point all protos have been +// parsed and so all extensions are known. +// +// Extension numbers for custom options may be chosen as follows: +// * For options which will only be used within a single application or +// organization, or for experimental options, use field numbers 50000 +// through 99999. It is up to you to ensure that you do not use the +// same number for multiple options. +// * For options which will be published and used publicly by multiple +// independent entities, e-mail protobuf-global-extension-registry@google.com +// to reserve extension numbers. Simply provide your project name (e.g. +// Objective-C plugin) and your project website (if available) -- there's no +// need to explain how you intend to use them. Usually you only need one +// extension number. You can declare multiple options with only one extension +// number by putting them in a sub-message. See the Custom Options section of +// the docs for examples: +// https://developers.google.com/protocol-buffers/docs/proto#options +// If this turns out to be popular, a web service will be set up +// to automatically assign option numbers. + +message FileOptions { + + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + optional string java_package = 1; + + + // Controls the name of the wrapper Java class generated for the .proto file. + // That class will always contain the .proto file's getDescriptor() method as + // well as any top-level extensions defined in the .proto file. + // If java_multiple_files is disabled, then all the other classes from the + // .proto file will be nested inside the single wrapper outer class. + optional string java_outer_classname = 8; + + // If enabled, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the wrapper class + // named by java_outer_classname. However, the wrapper class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + optional bool java_multiple_files = 10 [default = false]; + + // This option does nothing. + optional bool java_generate_equals_and_hash = 20 [deprecated=true]; + + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + optional bool java_string_check_utf8 = 27 [default = false]; + + + // Generated classes can be optimized for speed or code size. + enum OptimizeMode { + SPEED = 1; // Generate complete code for parsing, serialization, + // etc. + CODE_SIZE = 2; // Use ReflectionOps to implement these methods. + LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. + } + optional OptimizeMode optimize_for = 9 [default = SPEED]; + + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + optional string go_package = 11; + + + + + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + optional bool cc_generic_services = 16 [default = false]; + optional bool java_generic_services = 17 [default = false]; + optional bool py_generic_services = 18 [default = false]; + optional bool php_generic_services = 42 [default = false]; + + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + optional bool deprecated = 23 [default = false]; + + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + optional bool cc_enable_arenas = 31 [default = true]; + + + // Sets the objective c class prefix which is prepended to all objective c + // generated classes from this .proto. There is no default. + optional string objc_class_prefix = 36; + + // Namespace for generated classes; defaults to the package. + optional string csharp_namespace = 37; + + // By default Swift generators will take the proto package and CamelCase it + // replacing '.' with underscore and use that to prefix the types/symbols + // defined. When this options is provided, they will use this value instead + // to prefix the types/symbols defined. + optional string swift_prefix = 39; + + // Sets the php class prefix which is prepended to all php generated classes + // from this .proto. Default is empty. + optional string php_class_prefix = 40; + + // Use this option to change the namespace of php generated classes. Default + // is empty. When this option is empty, the package name will be used for + // determining the namespace. + optional string php_namespace = 41; + + // Use this option to change the namespace of php generated metadata classes. + // Default is empty. When this option is empty, the proto file name will be + // used for determining the namespace. + optional string php_metadata_namespace = 44; + + // Use this option to change the package of ruby generated classes. Default + // is empty. When this option is not set, the package name will be used for + // determining the ruby package. + optional string ruby_package = 45; + + + // The parser stores options it doesn't recognize here. + // See the documentation for the "Options" section above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. + // See the documentation for the "Options" section above. + extensions 1000 to max; + + reserved 38; +} + +message MessageOptions { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + optional bool message_set_wire_format = 1 [default = false]; + + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + optional bool no_standard_descriptor_accessor = 2 [default = false]; + + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + optional bool deprecated = 3 [default = false]; + + reserved 4, 5, 6; + + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementations still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + optional bool map_entry = 7; + + reserved 8; // javalite_serializable + reserved 9; // javanano_as_lite + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message FieldOptions { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + optional CType ctype = 1 [default = STRING]; + enum CType { + // Default mode. + STRING = 0; + + CORD = 1; + + STRING_PIECE = 2; + } + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. In proto3, only explicit setting it to + // false will avoid using packed encoding. + optional bool packed = 2; + + // The jstype option determines the JavaScript type used for values of the + // field. The option is permitted only for 64 bit integral and fixed types + // (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING + // is represented as JavaScript string, which avoids loss of precision that + // can happen when a large value is converted to a floating point JavaScript. + // Specifying JS_NUMBER for the jstype causes the generated JavaScript code to + // use the JavaScript "number" type. The behavior of the default option + // JS_NORMAL is implementation dependent. + // + // This option is an enum to permit additional types to be added, e.g. + // goog.math.Integer. + optional JSType jstype = 6 [default = JS_NORMAL]; + enum JSType { + // Use the default type. + JS_NORMAL = 0; + + // Use JavaScript strings. + JS_STRING = 1; + + // Use JavaScript numbers. + JS_NUMBER = 2; + } + + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outer message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + optional bool lazy = 5 [default = false]; + + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + optional bool deprecated = 3 [default = false]; + + // For Google-internal migration only. Do not use. + optional bool weak = 10 [default = false]; + + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; + + reserved 4; // removed jtype +} + +message OneofOptions { + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumOptions { + + // Set this option to true to allow mapping different tag names to the same + // value. + optional bool allow_alias = 2; + + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + optional bool deprecated = 3 [default = false]; + + reserved 5; // javanano_as_lite + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message EnumValueOptions { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + optional bool deprecated = 1 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message ServiceOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + optional bool deprecated = 33 [default = false]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + +message MethodOptions { + + // Note: Field numbers 1 through 32 are reserved for Google's internal RPC + // framework. We apologize for hoarding these numbers to ourselves, but + // we were already using them long before we decided to release Protocol + // Buffers. + + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + optional bool deprecated = 33 [default = false]; + + // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, + // or neither? HTTP based RPC implementation may choose GET verb for safe + // methods, and PUT verb for idempotent methods instead of the default POST. + enum IdempotencyLevel { + IDEMPOTENCY_UNKNOWN = 0; + NO_SIDE_EFFECTS = 1; // implies idempotent + IDEMPOTENT = 2; // idempotent, but may have side effects + } + optional IdempotencyLevel idempotency_level = 34 + [default = IDEMPOTENCY_UNKNOWN]; + + // The parser stores options it doesn't recognize here. See above. + repeated UninterpretedOption uninterpreted_option = 999; + + // Clients can define custom options in extensions of this message. See above. + extensions 1000 to max; +} + + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +message UninterpretedOption { + // The name of the uninterpreted option. Each string represents a segment in + // a dot-separated name. is_extension is true iff a segment represents an + // extension (denoted with parentheses in options specs in .proto files). + // E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents + // "foo.(bar.baz).qux". + message NamePart { + required string name_part = 1; + required bool is_extension = 2; + } + repeated NamePart name = 2; + + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + optional string identifier_value = 3; + optional uint64 positive_int_value = 4; + optional int64 negative_int_value = 5; + optional double double_value = 6; + optional bytes string_value = 7; + optional string aggregate_value = 8; +} + +// =================================================================== +// Optional source code info + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +message SourceCodeInfo { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendant. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + repeated Location location = 1; + message Location { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + repeated int32 path = 1 [packed = true]; + + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + repeated int32 span = 2 [packed = true]; + + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // leading_detached_comments will keep paragraphs of comments that appear + // before (but not connected to) the current element. Each paragraph, + // separated by empty lines, will be one comment element in the repeated + // field. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // // Detached comment for corge. This is not leading or trailing comments + // // to qux or corge because there are blank lines separating it from + // // both. + // + // // Detached comment for corge paragraph 2. + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + // + // // ignored detached comments. + optional string leading_comments = 3; + optional string trailing_comments = 4; + repeated string leading_detached_comments = 6; + } +} + +// Describes the relationship between generated code and its original source +// file. A GeneratedCodeInfo message is associated with only one generated +// source file, but may contain references to different source .proto files. +message GeneratedCodeInfo { + // An Annotation connects some span of text in generated code to an element + // of its generating .proto file. + repeated Annotation annotation = 1; + message Annotation { + // Identifies the element in the original source .proto file. This field + // is formatted the same as SourceCodeInfo.Location.path. + repeated int32 path = 1 [packed = true]; + + // Identifies the filesystem path to the original source .proto. + optional string source_file = 2; + + // Identifies the starting offset in bytes in the generated code + // that relates to the identified object. + optional int32 begin = 3; + + // Identifies the ending offset in bytes in the generated code that + // relates to the identified offset. The end offset should be one past + // the last relevant byte (so the length of the text = end - begin). + optional int32 end = 4; + } +} diff --git a/install/protos/google/protobuf/duration.proto b/install/protos/google/protobuf/duration.proto new file mode 100644 index 0000000..81c3e36 --- /dev/null +++ b/install/protos/google/protobuf/duration.proto @@ -0,0 +1,116 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/durationpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "DurationProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Duration represents a signed, fixed-length span of time represented +// as a count of seconds and fractions of seconds at nanosecond +// resolution. It is independent of any calendar and concepts like "day" +// or "month". It is related to Timestamp in that the difference between +// two Timestamp values is a Duration and it can be added or subtracted +// from a Timestamp. Range is approximately +-10,000 years. +// +// # Examples +// +// Example 1: Compute Duration from two Timestamps in pseudo code. +// +// Timestamp start = ...; +// Timestamp end = ...; +// Duration duration = ...; +// +// duration.seconds = end.seconds - start.seconds; +// duration.nanos = end.nanos - start.nanos; +// +// if (duration.seconds < 0 && duration.nanos > 0) { +// duration.seconds += 1; +// duration.nanos -= 1000000000; +// } else if (duration.seconds > 0 && duration.nanos < 0) { +// duration.seconds -= 1; +// duration.nanos += 1000000000; +// } +// +// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. +// +// Timestamp start = ...; +// Duration duration = ...; +// Timestamp end = ...; +// +// end.seconds = start.seconds + duration.seconds; +// end.nanos = start.nanos + duration.nanos; +// +// if (end.nanos < 0) { +// end.seconds -= 1; +// end.nanos += 1000000000; +// } else if (end.nanos >= 1000000000) { +// end.seconds += 1; +// end.nanos -= 1000000000; +// } +// +// Example 3: Compute Duration from datetime.timedelta in Python. +// +// td = datetime.timedelta(days=3, minutes=10) +// duration = Duration() +// duration.FromTimedelta(td) +// +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// +// +message Duration { + // Signed seconds of the span of time. Must be from -315,576,000,000 + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years + int64 seconds = 1; + + // Signed fractions of a second at nanosecond resolution of the span + // of time. Durations less than one second are represented with a 0 + // `seconds` field and a positive or negative `nanos` field. For durations + // of one second or more, a non-zero value for the `nanos` field must be + // of the same sign as the `seconds` field. Must be from -999,999,999 + // to +999,999,999 inclusive. + int32 nanos = 2; +} diff --git a/install/protos/google/protobuf/empty.proto b/install/protos/google/protobuf/empty.proto new file mode 100644 index 0000000..5f992de --- /dev/null +++ b/install/protos/google/protobuf/empty.proto @@ -0,0 +1,52 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option go_package = "google.golang.org/protobuf/types/known/emptypb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "EmptyProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option cc_enable_arenas = true; + +// A generic empty message that you can re-use to avoid defining duplicated +// empty messages in your APIs. A typical example is to use it as the request +// or the response type of an API method. For instance: +// +// service Foo { +// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); +// } +// +// The JSON representation for `Empty` is empty JSON object `{}`. +message Empty {} diff --git a/install/protos/google/protobuf/field_mask.proto b/install/protos/google/protobuf/field_mask.proto new file mode 100644 index 0000000..6b5104f --- /dev/null +++ b/install/protos/google/protobuf/field_mask.proto @@ -0,0 +1,245 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "FieldMaskProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/fieldmaskpb"; +option cc_enable_arenas = true; + +// `FieldMask` represents a set of symbolic field paths, for example: +// +// paths: "f.a" +// paths: "f.b.d" +// +// Here `f` represents a field in some root message, `a` and `b` +// fields in the message found in `f`, and `d` a field found in the +// message in `f.b`. +// +// Field masks are used to specify a subset of fields that should be +// returned by a get operation or modified by an update operation. +// Field masks also have a custom JSON encoding (see below). +// +// # Field Masks in Projections +// +// When used in the context of a projection, a response message or +// sub-message is filtered by the API to only contain those fields as +// specified in the mask. For example, if the mask in the previous +// example is applied to a response message as follows: +// +// f { +// a : 22 +// b { +// d : 1 +// x : 2 +// } +// y : 13 +// } +// z: 8 +// +// The result will not contain specific values for fields x,y and z +// (their value will be set to the default, and omitted in proto text +// output): +// +// +// f { +// a : 22 +// b { +// d : 1 +// } +// } +// +// A repeated field is not allowed except at the last position of a +// paths string. +// +// If a FieldMask object is not present in a get operation, the +// operation applies to all fields (as if a FieldMask of all fields +// had been specified). +// +// Note that a field mask does not necessarily apply to the +// top-level response message. In case of a REST get operation, the +// field mask applies directly to the response, but in case of a REST +// list operation, the mask instead applies to each individual message +// in the returned resource list. In case of a REST custom method, +// other definitions may be used. Where the mask applies will be +// clearly documented together with its declaration in the API. In +// any case, the effect on the returned resource/resources is required +// behavior for APIs. +// +// # Field Masks in Update Operations +// +// A field mask in update operations specifies which fields of the +// targeted resource are going to be updated. The API is required +// to only change the values of the fields as specified in the mask +// and leave the others untouched. If a resource is passed in to +// describe the updated values, the API ignores the values of all +// fields not covered by the mask. +// +// If a repeated field is specified for an update operation, new values will +// be appended to the existing repeated field in the target resource. Note that +// a repeated field is only allowed in the last position of a `paths` string. +// +// If a sub-message is specified in the last position of the field mask for an +// update operation, then new value will be merged into the existing sub-message +// in the target resource. +// +// For example, given the target message: +// +// f { +// b { +// d: 1 +// x: 2 +// } +// c: [1] +// } +// +// And an update message: +// +// f { +// b { +// d: 10 +// } +// c: [2] +// } +// +// then if the field mask is: +// +// paths: ["f.b", "f.c"] +// +// then the result will be: +// +// f { +// b { +// d: 10 +// x: 2 +// } +// c: [1, 2] +// } +// +// An implementation may provide options to override this default behavior for +// repeated and message fields. +// +// In order to reset a field's value to the default, the field must +// be in the mask and set to the default value in the provided resource. +// Hence, in order to reset all fields of a resource, provide a default +// instance of the resource and set all fields in the mask, or do +// not provide a mask as described below. +// +// If a field mask is not present on update, the operation applies to +// all fields (as if a field mask of all fields has been specified). +// Note that in the presence of schema evolution, this may mean that +// fields the client does not know and has therefore not filled into +// the request will be reset to their default. If this is unwanted +// behavior, a specific service may require a client to always specify +// a field mask, producing an error if not. +// +// As with get operations, the location of the resource which +// describes the updated values in the request message depends on the +// operation kind. In any case, the effect of the field mask is +// required to be honored by the API. +// +// ## Considerations for HTTP REST +// +// The HTTP kind of an update operation which uses a field mask must +// be set to PATCH instead of PUT in order to satisfy HTTP semantics +// (PUT must only be used for full updates). +// +// # JSON Encoding of Field Masks +// +// In JSON, a field mask is encoded as a single string where paths are +// separated by a comma. Fields name in each path are converted +// to/from lower-camel naming conventions. +// +// As an example, consider the following message declarations: +// +// message Profile { +// User user = 1; +// Photo photo = 2; +// } +// message User { +// string display_name = 1; +// string address = 2; +// } +// +// In proto a field mask for `Profile` may look as such: +// +// mask { +// paths: "user.display_name" +// paths: "photo" +// } +// +// In JSON, the same mask is represented as below: +// +// { +// mask: "user.displayName,photo" +// } +// +// # Field Masks and Oneof Fields +// +// Field masks treat fields in oneofs just as regular fields. Consider the +// following message: +// +// message SampleMessage { +// oneof test_oneof { +// string name = 4; +// SubMessage sub_message = 9; +// } +// } +// +// The field mask can be: +// +// mask { +// paths: "name" +// } +// +// Or: +// +// mask { +// paths: "sub_message" +// } +// +// Note that oneof type names ("test_oneof" in this case) cannot be used in +// paths. +// +// ## Field Mask Verification +// +// The implementation of any API method which has a FieldMask type field in the +// request should verify the included field paths, and return an +// `INVALID_ARGUMENT` error if any path is unmappable. +message FieldMask { + // The set of field mask paths. + repeated string paths = 1; +} diff --git a/install/protos/google/protobuf/source_context.proto b/install/protos/google/protobuf/source_context.proto new file mode 100644 index 0000000..06bfc43 --- /dev/null +++ b/install/protos/google/protobuf/source_context.proto @@ -0,0 +1,48 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "SourceContextProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/sourcecontextpb"; + +// `SourceContext` represents information about the source of a +// protobuf element, like the file in which it is defined. +message SourceContext { + // The path-qualified name of the .proto file that contained the associated + // protobuf element. For example: `"google/protobuf/source_context.proto"`. + string file_name = 1; +} diff --git a/install/protos/google/protobuf/struct.proto b/install/protos/google/protobuf/struct.proto new file mode 100644 index 0000000..0ac843c --- /dev/null +++ b/install/protos/google/protobuf/struct.proto @@ -0,0 +1,95 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/structpb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "StructProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// `Struct` represents a structured data value, consisting of fields +// which map to dynamically typed values. In some languages, `Struct` +// might be supported by a native representation. For example, in +// scripting languages like JS a struct is represented as an +// object. The details of that representation are described together +// with the proto support for the language. +// +// The JSON representation for `Struct` is JSON object. +message Struct { + // Unordered map of dynamically typed values. + map fields = 1; +} + +// `Value` represents a dynamically typed value which can be either +// null, a number, a string, a boolean, a recursive struct value, or a +// list of values. A producer of value is expected to set one of these +// variants. Absence of any variant indicates an error. +// +// The JSON representation for `Value` is JSON value. +message Value { + // The kind of value. + oneof kind { + // Represents a null value. + NullValue null_value = 1; + // Represents a double value. + double number_value = 2; + // Represents a string value. + string string_value = 3; + // Represents a boolean value. + bool bool_value = 4; + // Represents a structured value. + Struct struct_value = 5; + // Represents a repeated `Value`. + ListValue list_value = 6; + } +} + +// `NullValue` is a singleton enumeration to represent the null value for the +// `Value` type union. +// +// The JSON representation for `NullValue` is JSON `null`. +enum NullValue { + // Null value. + NULL_VALUE = 0; +} + +// `ListValue` is a wrapper around a repeated field of values. +// +// The JSON representation for `ListValue` is JSON array. +message ListValue { + // Repeated field of dynamically typed values. + repeated Value values = 1; +} diff --git a/install/protos/google/protobuf/timestamp.proto b/install/protos/google/protobuf/timestamp.proto new file mode 100644 index 0000000..3b2df6d --- /dev/null +++ b/install/protos/google/protobuf/timestamp.proto @@ -0,0 +1,147 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/timestamppb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TimestampProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// A Timestamp represents a point in time independent of any time zone or local +// calendar, encoded as a count of seconds and fractions of seconds at +// nanosecond resolution. The count is relative to an epoch at UTC midnight on +// January 1, 1970, in the proleptic Gregorian calendar which extends the +// Gregorian calendar backwards to year one. +// +// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +// second table is needed for interpretation, using a [24-hour linear +// smear](https://developers.google.com/time/smear). +// +// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +// restricting to that range, we ensure that we can convert to and from [RFC +// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +// +// # Examples +// +// Example 1: Compute Timestamp from POSIX `time()`. +// +// Timestamp timestamp; +// timestamp.set_seconds(time(NULL)); +// timestamp.set_nanos(0); +// +// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +// +// struct timeval tv; +// gettimeofday(&tv, NULL); +// +// Timestamp timestamp; +// timestamp.set_seconds(tv.tv_sec); +// timestamp.set_nanos(tv.tv_usec * 1000); +// +// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +// +// FILETIME ft; +// GetSystemTimeAsFileTime(&ft); +// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +// +// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +// Timestamp timestamp; +// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +// +// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +// +// long millis = System.currentTimeMillis(); +// +// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +// .setNanos((int) ((millis % 1000) * 1000000)).build(); +// +// +// Example 5: Compute Timestamp from Java `Instant.now()`. +// +// Instant now = Instant.now(); +// +// Timestamp timestamp = +// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +// .setNanos(now.getNano()).build(); +// +// +// Example 6: Compute Timestamp from current time in Python. +// +// timestamp = Timestamp() +// timestamp.GetCurrentTime() +// +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required. A proto3 JSON serializer should always use UTC (as indicated by +// "Z") when printing the Timestamp type and a proto3 JSON parser should be +// able to accept both UTC and other timezones (as indicated by an offset). +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard +// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using +// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D +// ) to obtain a formatter capable of generating timestamps in this format. +// +// +message Timestamp { + // Represents seconds of UTC time since Unix epoch + // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + // 9999-12-31T23:59:59Z inclusive. + int64 seconds = 1; + + // Non-negative fractions of a second at nanosecond resolution. Negative + // second values with fractions must still have non-negative nanos values + // that count forward in time. Must be from 0 to 999,999,999 + // inclusive. + int32 nanos = 2; +} diff --git a/install/protos/google/protobuf/type.proto b/install/protos/google/protobuf/type.proto new file mode 100644 index 0000000..d3f6a68 --- /dev/null +++ b/install/protos/google/protobuf/type.proto @@ -0,0 +1,187 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package google.protobuf; + +import "google/protobuf/any.proto"; +import "google/protobuf/source_context.proto"; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option java_package = "com.google.protobuf"; +option java_outer_classname = "TypeProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/typepb"; + +// A protocol buffer message type. +message Type { + // The fully qualified message name. + string name = 1; + // The list of fields. + repeated Field fields = 2; + // The list of types appearing in `oneof` definitions in this type. + repeated string oneofs = 3; + // The protocol buffer options. + repeated Option options = 4; + // The source context. + SourceContext source_context = 5; + // The source syntax. + Syntax syntax = 6; +} + +// A single field of a message type. +message Field { + // Basic field types. + enum Kind { + // Field type unknown. + TYPE_UNKNOWN = 0; + // Field type double. + TYPE_DOUBLE = 1; + // Field type float. + TYPE_FLOAT = 2; + // Field type int64. + TYPE_INT64 = 3; + // Field type uint64. + TYPE_UINT64 = 4; + // Field type int32. + TYPE_INT32 = 5; + // Field type fixed64. + TYPE_FIXED64 = 6; + // Field type fixed32. + TYPE_FIXED32 = 7; + // Field type bool. + TYPE_BOOL = 8; + // Field type string. + TYPE_STRING = 9; + // Field type group. Proto2 syntax only, and deprecated. + TYPE_GROUP = 10; + // Field type message. + TYPE_MESSAGE = 11; + // Field type bytes. + TYPE_BYTES = 12; + // Field type uint32. + TYPE_UINT32 = 13; + // Field type enum. + TYPE_ENUM = 14; + // Field type sfixed32. + TYPE_SFIXED32 = 15; + // Field type sfixed64. + TYPE_SFIXED64 = 16; + // Field type sint32. + TYPE_SINT32 = 17; + // Field type sint64. + TYPE_SINT64 = 18; + } + + // Whether a field is optional, required, or repeated. + enum Cardinality { + // For fields with unknown cardinality. + CARDINALITY_UNKNOWN = 0; + // For optional fields. + CARDINALITY_OPTIONAL = 1; + // For required fields. Proto2 syntax only. + CARDINALITY_REQUIRED = 2; + // For repeated fields. + CARDINALITY_REPEATED = 3; + } + + // The field type. + Kind kind = 1; + // The field cardinality. + Cardinality cardinality = 2; + // The field number. + int32 number = 3; + // The field name. + string name = 4; + // The field type URL, without the scheme, for message or enumeration + // types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. + string type_url = 6; + // The index of the field type in `Type.oneofs`, for message or enumeration + // types. The first type has index 1; zero means the type is not in the list. + int32 oneof_index = 7; + // Whether to use alternative packed wire representation. + bool packed = 8; + // The protocol buffer options. + repeated Option options = 9; + // The field JSON name. + string json_name = 10; + // The string value of the default value of this field. Proto2 syntax only. + string default_value = 11; +} + +// Enum type definition. +message Enum { + // Enum type name. + string name = 1; + // Enum value definitions. + repeated EnumValue enumvalue = 2; + // Protocol buffer options. + repeated Option options = 3; + // The source context. + SourceContext source_context = 4; + // The source syntax. + Syntax syntax = 5; +} + +// Enum value definition. +message EnumValue { + // Enum value name. + string name = 1; + // Enum value number. + int32 number = 2; + // Protocol buffer options. + repeated Option options = 3; +} + +// A protocol buffer option, which can be attached to a message, field, +// enumeration, etc. +message Option { + // The option's name. For protobuf built-in options (options defined in + // descriptor.proto), this is the short name. For example, `"map_entry"`. + // For custom options, it should be the fully-qualified name. For example, + // `"google.api.http"`. + string name = 1; + // The option's value packed in an Any message. If the value is a primitive, + // the corresponding wrapper type defined in google/protobuf/wrappers.proto + // should be used. If the value is an enum, it should be stored as an int32 + // value using the google.protobuf.Int32Value type. + Any value = 2; +} + +// The syntax in which a protocol buffer element is defined. +enum Syntax { + // Syntax `proto2`. + SYNTAX_PROTO2 = 0; + // Syntax `proto3`. + SYNTAX_PROTO3 = 1; +} diff --git a/install/protos/google/protobuf/wrappers.proto b/install/protos/google/protobuf/wrappers.proto new file mode 100644 index 0000000..d49dd53 --- /dev/null +++ b/install/protos/google/protobuf/wrappers.proto @@ -0,0 +1,123 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Wrappers for primitive (non-message) types. These types are useful +// for embedding primitives in the `google.protobuf.Any` type and for places +// where we need to distinguish between the absence of a primitive +// typed field and its default value. +// +// These wrappers have no meaningful use within repeated fields as they lack +// the ability to detect presence on individual elements. +// These wrappers have no meaningful use within a map or a oneof since +// individual entries of a map or fields of a oneof can already detect presence. + +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/protobuf/types/known/wrapperspb"; +option java_package = "com.google.protobuf"; +option java_outer_classname = "WrappersProto"; +option java_multiple_files = true; +option objc_class_prefix = "GPB"; + +// Wrapper message for `double`. +// +// The JSON representation for `DoubleValue` is JSON number. +message DoubleValue { + // The double value. + double value = 1; +} + +// Wrapper message for `float`. +// +// The JSON representation for `FloatValue` is JSON number. +message FloatValue { + // The float value. + float value = 1; +} + +// Wrapper message for `int64`. +// +// The JSON representation for `Int64Value` is JSON string. +message Int64Value { + // The int64 value. + int64 value = 1; +} + +// Wrapper message for `uint64`. +// +// The JSON representation for `UInt64Value` is JSON string. +message UInt64Value { + // The uint64 value. + uint64 value = 1; +} + +// Wrapper message for `int32`. +// +// The JSON representation for `Int32Value` is JSON number. +message Int32Value { + // The int32 value. + int32 value = 1; +} + +// Wrapper message for `uint32`. +// +// The JSON representation for `UInt32Value` is JSON number. +message UInt32Value { + // The uint32 value. + uint32 value = 1; +} + +// Wrapper message for `bool`. +// +// The JSON representation for `BoolValue` is JSON `true` and `false`. +message BoolValue { + // The bool value. + bool value = 1; +} + +// Wrapper message for `string`. +// +// The JSON representation for `StringValue` is JSON string. +message StringValue { + // The string value. + string value = 1; +} + +// Wrapper message for `bytes`. +// +// The JSON representation for `BytesValue` is JSON string. +message BytesValue { + // The bytes value. + bytes value = 1; +} diff --git a/install/submodules/trpc-protocol/CONTRIBUTING.md b/install/submodules/trpc-protocol/CONTRIBUTING.md new file mode 100644 index 0000000..95a5466 --- /dev/null +++ b/install/submodules/trpc-protocol/CONTRIBUTING.md @@ -0,0 +1,37 @@ +Thank you for your interest and support in tRPC! + +We welcome and appreciate any form of contribution, including but not limited to submitting issues, providing improvement suggestions, improving documentation, fixing bugs, and adding features. This document aims to provide you with a detailed contribution guide to help you better participate in the project. Please read this guide carefully before contributing and make sure to follow the rules here. We look forward to working with you to make this project better together! + +## Before submitting an issue + +please make sure that you have reviewed the project's documentation, FAQ, and existing issues. This can avoid submitting known issues repeatedly and save your and the project maintainer's time. When you decide to submit an issue, please follow these rules: +- Select appropriate labels for the issue. This helps us to quickly locate the problem and solve it as soon as possible. +- Ensure that the issue title is concise and accurately summarizes the problem. Avoid using vague words such as "problem" or "error". +In the issue description, please provide a detailed description of the problem you encountered. This includes but is not limited to the following: +- Problem description: briefly describe the symptoms and impact of the problem. +- Reproduction steps: describe in detail how to reproduce the problem, so that we can locate and solve the problem more quickly. +- Environment information: relevant information including operating system, browser, project version, etc. +- Error log: if there are relevant error logs, please provide them. +- Expected results: describe what the correct result should be. +- Screenshots or screen recordings: if possible, provide screenshots or screen recordings of the problem. +Please be polite and friendly. We attach great importance to the environment of the project and hope that everyone can grow together in a friendly and inclusive environment. + +## Rules for submitting PRs + +We welcome you to submit code for the project. Before submitting a PR, please make sure that you have read this contribution guide. Here are some suggestions and rules regarding submitting PRs. Please read them carefully before submitting: +- Ensure that your code conforms to the project's code specifications. This includes but is not limited to code style, comment specifications, etc. This helps us to maintain the cleanliness and consistency of the project. +- Before submitting a PR, please make sure that you have tested your code locally. Ensure that the code has no obvious errors and can run normally. +- Please select appropriate labels for your PR. This helps us to process your PR more quickly. +- Ensure that your PR title is concise and accurately summarizes your changes. Avoid using vague words such as "update" or "modify". +- In the PR description, please provide a detailed description of your changes. This includes but is not limited to the following: + - Reason for modification: briefly explain why this modification is necessary. + - Modification content: describe in detail what you have modified and how you have implemented it. + - Scope of impact: describe the functions or modules that may be affected by the modification. + - Testing: describe the testing you have done locally and the results. +- If your PR resolves a certain issue, please associate the corresponding issue in the PR description. For example: Fixes #123. + +## Communication and Consultation + +We welcome you to participate in the project's communication and consultation. You can interact with us through the following channels: +- Submit your questions or suggestions in the project's discussions. +- Join our technical communication group. diff --git a/install/submodules/trpc-protocol/CONTRIBUTING_cn.md b/install/submodules/trpc-protocol/CONTRIBUTING_cn.md new file mode 100644 index 0000000..e69de29 diff --git a/install/submodules/trpc-protocol/LICENSE b/install/submodules/trpc-protocol/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/install/submodules/trpc-protocol/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/install/submodules/trpc-protocol/Makefile b/install/submodules/trpc-protocol/Makefile new file mode 100644 index 0000000..6a425ce --- /dev/null +++ b/install/submodules/trpc-protocol/Makefile @@ -0,0 +1,26 @@ +DIR=pb/go +INCLUDE_GOOGLE_PB_PATH=/usr/local/include +all: + rm -rf $(DIR) + mkdir -p $(DIR) + protoc -I$(INCLUDE_GOOGLE_PB_PATH) -I.\ + --go_out=paths=source_relative:./$(DIR) \ + ./trpc/api/annotations.proto \ + ./trpc/api/http.proto + protoc -I$(INCLUDE_GOOGLE_PB_PATH) -I.\ + --go_out=./$(DIR) \ + ./trpc/trpc.proto \ + ./trpc/proto/trpc_options.proto \ + ./trpc/swagger/swagger.proto \ + ./trpc/validate/validate.proto + mv $(DIR)/trpc.group/trpc/trpc-protocol/pb/go/trpc/* $(DIR)/trpc + rm -rf $(DIR)/trpc.group + cd ./$(DIR)/trpc && go mod init trpc.group/trpc/trpc-protocol/$(DIR)/trpc && go mod tidy && cd - + +.PHONY: test clean + +test: + ./testbuild.sh + +clean: + rm -rf $(DIR) diff --git a/install/submodules/trpc-protocol/README.md b/install/submodules/trpc-protocol/README.md new file mode 100644 index 0000000..2ac8235 --- /dev/null +++ b/install/submodules/trpc-protocol/README.md @@ -0,0 +1,51 @@ +# tRPC - A multi-language, plug-in, high-performance rpc framework + +## What is tRPC + +tRPC is a high-performance RPC development framework which is designed based on the concept of plug-in,the overall design follows the following principles: +- Easy to use: business developer should be simple and convenient for service development based on the framework. +- Intercommunication: Different servers may use different message communication types, encoding and decompression methods,the framework design and implementation should be able to solve the intercommunication with these servers. +- General & High Performance: The framework should be applicable to a broad class of application scenarios while sacrificing little in performance when compared to a specific application scenarios framework. +- Plugin: The entire framework should be layered and modularized according to features in terms of architecture design and specific implementation. It is best for each core module to evolve independently. For capabilities related to service governance (such as naming/config/metrics/logging/tracing/auth, etc.), Extension points should be provided to allow plugging in these features and providing default implementations; + +## Features +- Works across languages:The communication between the client and the server is based on protobuf IDL, and the current open source version supports languages such as c++/go/java. +- Support multi-protocols:A multi-protocol server that is convenient and fast to build. The protocols include common protocols (such as http/grpc), and other custom protocols. +- Stream RPC: In addition to supporting unary rpc call, tRPC also supports streaming rpc call, which better solves the application scenarios of large data transmission, such as: large file upload/download,message push, speech recognition/video understanding, etc. +- Rich plug-in ecology: tRPC provides plug-ins that are interoperable with mainstream ecosystems (such as grpc ecology/consul/promethues/opentelemetry, etc.), which is convenient for businesses to choose their own service governance ecology. +- Scalability: Based on the plug-in design of the framework, the business can use the plug-in factory and interceptor filter for personalized secondary development to expand the framework capabilities and meet business needs, such as: parameter validation, authentication, request replay, etc. +- Flow control and overload protection: In order to prevent services from being busy or overloaded due to sudden traffic surges or server failures, tRPC implements flow control and overload protection plug-ins in different application scenarios to ensure service availability; + +## Supported languages + +- [C++]() +- [Go]() +- [Java]() + +## To start using tRPC + +Per-language quickstart guides and tutorials can be found in the +[documentation section on the trpc.io website](https://trpc.group/docs/). Code +examples are available in the examplesdirectory. + +- [C++](): [quick-start]() / [user-guide]() / [examples]() +- [Go](): [quick-start]() / [user-guide]() / [examples]() +- [Java](): [quick-start]() / [user-guide]() / [examples]() + +## To start developing tRPC + +Contributions are welcome! + +Please read [How to contribute](CONTRIBUTING.md) which will guide you through +the entire workflow of how to build the source code, how to run the tests, and +how to contribute changes to the tRPC codebase. + +## Troubleshooting + +Sometimes things go wrong. Please check out the +[Troubleshooting guide](TROUBLESHOOTING.md) if you are experiencing issues with +tRPC. + +## License + +Apache License Version 2.0 \ No newline at end of file diff --git a/install/submodules/trpc-protocol/README_cn.md b/install/submodules/trpc-protocol/README_cn.md new file mode 100644 index 0000000..ba13638 --- /dev/null +++ b/install/submodules/trpc-protocol/README_cn.md @@ -0,0 +1,45 @@ +# tRPC - 多语言、插件化、高性能的rpc开发框架 + +## tRPC是什么 + +tRPC是基于插件化理念设计的一款高性能RPC开发框架,整体设计遵循以下原则: +- 使用简单:业务开发基于框架进行服务开发应该简单方便 +- 互通:不同的服务可能使用不同的消息通信类型、编解码和解压缩方式,框架设计和实现上应能解决与这些服务的互通; +- 通用且高性能:框架应该适用于绝大多数应用场景,相比针对特定应用场景的框架,框架只会牺牲一点性能; +- 插件化:整个框架在架构设计和具体实现上应该按特性进行分层和模块化,各个核心模块最好能够独立演进,对于服务治理相关的能力(比如naming/config/metrics/logging/tracing/auth等),应该提供扩展点,以允许插入这些特性和提供默认实现; + +## 特点 +- 跨语言:客户端与服务端通信基于protobuf IDL,目前开源版本支持c++/go/java等语言; +- 多通信协议:方便快速构建的多协议服务, 协议包括通用协议http/grpc,以及各种自定义协议; +- 流式rpc: 除了支持一应一答的rpc调用方式外,tRPC还支持流式rpc调用,更好地解决大文件上传/下载、消息push、ai类语音识别/视频理解等大数据传输的应用场景; +- 丰富插件生态:tRPC提供了与业界主流生态互通的插件(比如grpc生态/consul/promethues/opentelemetry等),方便业务选择适合自己的服务治理生态; +- 可扩展性:基于框架插件化的设计,业务可以使用插件工厂和拦截器filter进行个性化的二次开发来扩展框架能力,满足业务需求,比如:RPC请求参数校验、鉴权、请求录制等; +- 流控和过载保护:为了防止业务因为访问量突增或服务器故障造成服务整体的繁忙或者过载不可用,tRPC实现了不同应用场景下的流量控制和过载保护插件,保证服务的可用性; + +## 支持语言 + +- [C++]() +- [Go]() +- [Java]() + +## 如何使用tRPC + +可以在[documentation section on the trpc.io website](https://trpc.group/docs/)找到每个语言的快速入门、用户指南和代码示例等学习资料. + +- [C++](): [quick-start]() / [user-guide]() / [examples]() +- [Go](): [quick-start]() / [user-guide]() / [examples]() +- [Java](): [quick-start]() / [user-guide]() / [examples]() + +## 如何为tRPC做贡献 + +非常欢迎大家给tRPC做贡献! + +建议您在为tRPC贡献之前, 先阅读一下[How to contribute](CONTRIBUTING.md), 它会指导你了解贡献代码的整个流程, 比如: 如何提pr/如何构建代码/如何运行单元测试等; + +## 遇到问题怎么办 + +如果使用tRPC过程遇到问题, 可以先看看[Troubleshooting guide](TROUBLESHOOTING.md), 它会告诉你使用tRPC遇到各种问题的处理方式, 比如: 如何提issue/一些常见问题如何排查等; + +## License + +Apache License Version 2.0 \ No newline at end of file diff --git a/install/submodules/trpc-protocol/WORKSPACE b/install/submodules/trpc-protocol/WORKSPACE new file mode 100644 index 0000000..4a8401c --- /dev/null +++ b/install/submodules/trpc-protocol/WORKSPACE @@ -0,0 +1,16 @@ +workspace(name = "trpc_protocol") + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_protobuf", + sha256 = "d0f5f605d0d656007ce6c8b5a82df3037e1d8fe8b121ed42e536f569dec16113", + strip_prefix = "protobuf-3.14.0", + urls = [ + "https://github.com/protocolbuffers/protobuf/archive/v3.14.0.tar.gz", + ], +) + +load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") + +protobuf_deps() diff --git a/install/submodules/trpc-protocol/docs/images/trpc-protocol.png b/install/submodules/trpc-protocol/docs/images/trpc-protocol.png new file mode 100644 index 0000000..925d69f Binary files /dev/null and b/install/submodules/trpc-protocol/docs/images/trpc-protocol.png differ diff --git a/install/submodules/trpc-protocol/docs/protocol_design.md b/install/submodules/trpc-protocol/docs/protocol_design.md new file mode 100644 index 0000000..e27e9ca --- /dev/null +++ b/install/submodules/trpc-protocol/docs/protocol_design.md @@ -0,0 +1,427 @@ +[TOC] + +# Capabilities and Demands + +| Capabilities |Demands | +| ------------ | ------------ | +| RPC | remote interface call like local interface call | +| Stream | the protocol should be able to solve the problem of transmitting large data packets and meet the scenario of streaming data transmission. | +| High Performance | the protocol design and implementation need to consider performance issues| +| Compatibility & Scalability | the protocol design and implementation should have forward compatibility and scalability | +| Support Multiple Serialization | the protocol design should support multiple serialization methods, such as protobuf, JSON, etc. | +| Support multiple Decompression | the protocol design should support multiple decompression methods. | +| Request Timeout Control | The protocol should provide the ability to control request timeout | +| Passing Tracing Information | The protocol should provide the ability to pass tracing information | +| Passing Auth Information | The protocol should provide the ability to pass auth information | +| Passing Dyeing Information | The protocol should provide the ability to pass dyeing information | +| Passing Custom Business Information | The protocol should provide the ability to pass custom business information | + +# Design And Implementation + +## Protocol Design + +![ 'image.png'](/docs/images/trpc-protocol.png) + +for unary RPC(one-request-one-response), the entire data packet = Fix Header(16 bytes)+ Unary Header + Unary Body. + +for stream RPC, the entire data packet = Fix Header(16 bytes)+ Stream Frame(Init/Data/Feeback/CLose) + +the complete protocol definition, please see [trpc.proto](/trpc/trpc.proto) + +## Protocol Details +### Fixed Header +- The first 2 bytes: + The first two bytes of the protocol are magic numbers, indicating the start of the trpc frame, which is 0x930. + +- The 3rd byte: the data frame type of the packet + +```protobuf +// Two types are currently supported: +// 1. The data frame type for unary(one-response-one-response) +// 2. The data frame type for stream +enum TrpcDataFrameType { +TRPC_UNARY_FRAME = 0x00; + +TRPC_STREAM_FRAME = 0x01; +} +``` + +- The 4th byte: streaming frame type, only valid when the data frame type is `TRPC_STREAM_FRAME` + +```protobuf +// Four types are currently supported: +// `INIT` frame: FIXHEADER + TrpcStreamInitMeta +// `DATA` frame: FIXHEADER + body (business serialized data) +// `FEEDBACK` frame: FIXHEADER + TrpcStreamFeedBackMeta (triggered strategy: high/low water level and timer) +// `CLOSE` frame: FIXHEADER + TrpcStreamCloseMeta +enum TrpcStreamFrameType { +TRPC_UNARY = 0x00; + +TRPC_STREAM_FRAME_INIT = 0x01; + +TRPC_STREAM_FRAME_DATA = 0x02; + +TRPC_STREAM_FRAME_FEEDBACK = 0x03; + +TRPC_STREAM_FRAME_CLOSE = 0x04; +} +``` + +- The 5-8 bytes, the total size of the packet + +For unary(one response one response), total data size = fixed header size + header size + body size + +For stream, total data size = fixed header size + stream frame size + +- The 9-10 bytes + +For unary(one response one response), header size + +For stream, set 0 + +- The 11-14 bytes + +For unary(one response one response), unique-id + +For stream, stream-id + +stream-id needs to be unique in a single connection + +- The 15 byte, the version of trpc protocol + +- The 16 byte, reserved field + +### The Header of Unary + +After 16 bytes, for unary(one-response-one-response), it corresponds to the header of the protocol, which is divided into request header and response header. + +### Request Header + +```protobuf +// The request header for unary +message RequestProtocol { + // The version of protocol + // The specific value corresponds to `TrpcProtoVersion` + uint32 version = 1; + + // Call type + // eg: unary, one-way + // The specific value corresponds to `TrpcCallType` + uint32 call_type = 2; + + // The unique id of the request(on the conneciton) + uint32 request_id = 3; + + // The timeout of the request(ms) + uint32 timeout = 4; + + // Caller name + // The specification format: trpc.application_name.server_name.proto_service_name, 4 segments + bytes caller = 5; + + // Callee name + // The specification format: trpc.application_name.server_name.proto_service_name[.interface_name] + bytes callee = 6; + + // Interface name of callee + // The specification format: /package.service_name/interface_name + bytes func = 7; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 8; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 9; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 10; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 11; + + // The size of attachment data + uint32 attachment_size = 12; +} +``` + +### Response Header + +```protobuf +// The response header for unary +message ResponseProtocol { + // The version of protocol + // The specific value corresponds to `TrpcProtoVersion` + uint32 version = 1; + + // Call type + // eg: unary, one-way + // The specific value corresponds to `TrpcCallType` + uint32 call_type = 2; + + // The unique id of the request(on the conneciton) + uint32 request_id = 3; + + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 4; + + // The error code of the interface + // 0 means success, other means failure + int32 func_ret = 5; + + // The result information when the call fails + bytes error_msg = 6; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 7; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + map trans_info = 8; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 9; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 10; + + // The size of attachment data + uint32 attachment_size = 12; +} +``` + +### Stream Frame + +After 16 bytes, for stream, it is followed by the stream frame + +Divided into init, data, feedback, close frame. + +- Init Frame is used for stream initialization + +- Data Frame is used to transmit streaming data + +- Feedback Frame is used to transmit flow control messages + +- Close Frame is used to close the stream + +#### Init Frame + +```protobuf +// The message definition of stream `INIT` frame +message TrpcStreamInitMeta { + // request meta information + TrpcStreamInitRequestMeta request_meta = 1; + + // response meta information + TrpcStreamInitResponseMeta response_meta = 2; + + // The window size is notified by the receiver to the sender + uint32 init_window_size = 3; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 4; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 5; +} +``` + +```protobuf +// The request meta information definition of stream `INIT` frame +message TrpcStreamInitRequestMeta { + // Caller name + // The specification format: trpc.application_name.server_name.proto_service_name, 4 segments + bytes caller = 1; + + // Callee name + // The specification format: trpc.application_name.server_name.proto_service_name[.interface_name] + bytes callee = 2; + + // Interface name of callee + // The specification format: /package.service_name/interface_name + bytes func = 3; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 4; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 5; +}; +``` + +```protobuf +// The response meta information definition of stream `INIT` frame +message TrpcStreamInitResponseMeta { + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 1; + + // The result information when the call fails + bytes error_msg = 2; +}; +``` + +#### Data Frame + +The data frame corresponds to the message body of the actual request + + +#### Feedback Frame + +```protobuf +// The meta information definition of stream `FEEDBACK` frame +message TrpcStreamFeedBackMeta { + // increased window size + uint32 window_size_increment = 1; +} +``` + +#### Close Frame + +Close frame is divided into normal Close and abnormal Close (Reset) + +```protobuf +// The closed type of trpc stream protocol +enum TrpcStreamCloseType { + // normal closes unidirectional flow + TRPC_STREAM_CLOSE = 0; + + // Exception closes bidirectional stream + TRPC_STREAM_RESET = 1; +} +``` + +```protobuf +// The meta information definition of trpc stream protocol for closing stream +message TrpcStreamCloseMeta { + // The type of stream closure, close one end, or close all + int32 close_type = 1; + + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 2; + + // The result information when the call fails + bytes msg = 3; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 4; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 5; + + // The error code of the interface + // 0 means success, other means failure + int32 func_ret = 6; +} +``` + + +# 3 IDL + +tRPC's IDL is based on Protobuf + +Unary IDL + +```protobuf +syntax = "proto3"; + +package proto; + +service StreamService { + rpc List(Request) returns ( Response) {}; + rpc Record( Request) returns (Response) {}; + rpc Route( StreamRequest) returns ( Response) {}; +} + + +message Point { + string name = 1; + int32 value = 2; +} + +message Request { + Point pt = 1; +} + +message Response { + Point pt = 1; +} +``` + + +Stream IDL + +Support: + +- Server-side streaming RPC +- Client Streaming RPC +- Bidirectional streaming RPC + +```protobuf +syntax = "proto3"; + +package proto; + +service StreamService { + rpc List(StreamRequest) returns (stream StreamResponse) {}; + rpc Record(stream StreamRequest) returns (StreamResponse) {}; + rpc Route(stream StreamRequest) returns (stream StreamResponse) {}; +} + + +message StreamPoint { + string name = 1; + int32 value = 2; +} + +message StreamRequest { + StreamPoint pt = 1; +} + +message StreamResponse { + StreamPoint pt = 1; +} +``` diff --git a/install/submodules/trpc-protocol/pb/go/trpc/api/annotations.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/api/annotations.pb.go new file mode 100644 index 0000000..351019a --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/api/annotations.pb.go @@ -0,0 +1,99 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/api/annotations.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_trpc_api_annotations_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*HttpRule)(nil), + Field: 50201, + Name: "trpc.api.http", + Tag: "bytes,50201,opt,name=http", + Filename: "trpc/api/annotations.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional trpc.api.HttpRule http = 50201; + E_Http = &file_trpc_api_annotations_proto_extTypes[0] +) + +var File_trpc_api_annotations_proto protoreflect.FileDescriptor + +var file_trpc_api_annotations_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x13, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x48, 0x0a, + 0x04, 0x68, 0x74, 0x74, 0x70, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x99, 0x88, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, + 0x65, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x42, 0x4d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x74, + 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x65, 0x78, 0x74, 0x5a, 0x2c, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2d, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, + 0x70, 0x63, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_trpc_api_annotations_proto_goTypes = []interface{}{ + (*descriptorpb.MethodOptions)(nil), // 0: google.protobuf.MethodOptions + (*HttpRule)(nil), // 1: trpc.api.HttpRule +} +var file_trpc_api_annotations_proto_depIdxs = []int32{ + 0, // 0: trpc.api.http:extendee -> google.protobuf.MethodOptions + 1, // 1: trpc.api.http:type_name -> trpc.api.HttpRule + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 1, // [1:2] is the sub-list for extension type_name + 0, // [0:1] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_trpc_api_annotations_proto_init() } +func file_trpc_api_annotations_proto_init() { + if File_trpc_api_annotations_proto != nil { + return + } + file_trpc_api_http_proto_init() + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_api_annotations_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_trpc_api_annotations_proto_goTypes, + DependencyIndexes: file_trpc_api_annotations_proto_depIdxs, + ExtensionInfos: file_trpc_api_annotations_proto_extTypes, + }.Build() + File_trpc_api_annotations_proto = out.File + file_trpc_api_annotations_proto_rawDesc = nil + file_trpc_api_annotations_proto_goTypes = nil + file_trpc_api_annotations_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/pb/go/trpc/api/http.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/api/http.pb.go new file mode 100644 index 0000000..a8635bb --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/api/http.pb.go @@ -0,0 +1,404 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/api/http.proto + +package api + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type HttpRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"` + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + // + // Types that are assignable to Pattern: + // + // *HttpRule_Get + // *HttpRule_Put + // *HttpRule_Post + // *HttpRule_Delete + // *HttpRule_Patch + // *HttpRule_Custom + Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"` + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + Body string `protobuf:"bytes,7,opt,name=body,proto3" json:"body,omitempty"` + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + ResponseBody string `protobuf:"bytes,12,opt,name=response_body,json=responseBody,proto3" json:"response_body,omitempty"` + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings,proto3" json:"additional_bindings,omitempty"` +} + +func (x *HttpRule) Reset() { + *x = HttpRule{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_api_http_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HttpRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HttpRule) ProtoMessage() {} + +func (x *HttpRule) ProtoReflect() protoreflect.Message { + mi := &file_trpc_api_http_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HttpRule.ProtoReflect.Descriptor instead. +func (*HttpRule) Descriptor() ([]byte, []int) { + return file_trpc_api_http_proto_rawDescGZIP(), []int{0} +} + +func (x *HttpRule) GetSelector() string { + if x != nil { + return x.Selector + } + return "" +} + +func (m *HttpRule) GetPattern() isHttpRule_Pattern { + if m != nil { + return m.Pattern + } + return nil +} + +func (x *HttpRule) GetGet() string { + if x, ok := x.GetPattern().(*HttpRule_Get); ok { + return x.Get + } + return "" +} + +func (x *HttpRule) GetPut() string { + if x, ok := x.GetPattern().(*HttpRule_Put); ok { + return x.Put + } + return "" +} + +func (x *HttpRule) GetPost() string { + if x, ok := x.GetPattern().(*HttpRule_Post); ok { + return x.Post + } + return "" +} + +func (x *HttpRule) GetDelete() string { + if x, ok := x.GetPattern().(*HttpRule_Delete); ok { + return x.Delete + } + return "" +} + +func (x *HttpRule) GetPatch() string { + if x, ok := x.GetPattern().(*HttpRule_Patch); ok { + return x.Patch + } + return "" +} + +func (x *HttpRule) GetCustom() *CustomHttpPattern { + if x, ok := x.GetPattern().(*HttpRule_Custom); ok { + return x.Custom + } + return nil +} + +func (x *HttpRule) GetBody() string { + if x != nil { + return x.Body + } + return "" +} + +func (x *HttpRule) GetResponseBody() string { + if x != nil { + return x.ResponseBody + } + return "" +} + +func (x *HttpRule) GetAdditionalBindings() []*HttpRule { + if x != nil { + return x.AdditionalBindings + } + return nil +} + +type isHttpRule_Pattern interface { + isHttpRule_Pattern() +} + +type HttpRule_Get struct { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + Get string `protobuf:"bytes,2,opt,name=get,proto3,oneof"` +} + +type HttpRule_Put struct { + // Maps to HTTP PUT. Used for replacing a resource. + Put string `protobuf:"bytes,3,opt,name=put,proto3,oneof"` +} + +type HttpRule_Post struct { + // Maps to HTTP POST. Used for creating a resource or performing an action. + Post string `protobuf:"bytes,4,opt,name=post,proto3,oneof"` +} + +type HttpRule_Delete struct { + // Maps to HTTP DELETE. Used for deleting a resource. + Delete string `protobuf:"bytes,5,opt,name=delete,proto3,oneof"` +} + +type HttpRule_Patch struct { + // Maps to HTTP PATCH. Used for updating a resource. + Patch string `protobuf:"bytes,6,opt,name=patch,proto3,oneof"` +} + +type HttpRule_Custom struct { + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,proto3,oneof"` +} + +func (*HttpRule_Get) isHttpRule_Pattern() {} + +func (*HttpRule_Put) isHttpRule_Pattern() {} + +func (*HttpRule_Post) isHttpRule_Pattern() {} + +func (*HttpRule_Delete) isHttpRule_Pattern() {} + +func (*HttpRule_Patch) isHttpRule_Pattern() {} + +func (*HttpRule_Custom) isHttpRule_Pattern() {} + +// A custom pattern is used for defining custom HTTP verb. +type CustomHttpPattern struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of this custom HTTP verb. + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + // The path matched by this custom verb. + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *CustomHttpPattern) Reset() { + *x = CustomHttpPattern{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_api_http_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CustomHttpPattern) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CustomHttpPattern) ProtoMessage() {} + +func (x *CustomHttpPattern) ProtoReflect() protoreflect.Message { + mi := &file_trpc_api_http_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CustomHttpPattern.ProtoReflect.Descriptor instead. +func (*CustomHttpPattern) Descriptor() ([]byte, []int) { + return file_trpc_api_http_proto_rawDescGZIP(), []int{1} +} + +func (x *CustomHttpPattern) GetKind() string { + if x != nil { + return x.Kind + } + return "" +} + +func (x *CustomHttpPattern) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +var File_trpc_api_http_proto protoreflect.FileDescriptor + +var file_trpc_api_http_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x70, 0x69, 0x22, + 0xd6, 0x02, 0x0a, 0x08, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x03, + 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x03, 0x70, 0x75, 0x74, + 0x12, 0x14, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x16, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x35, 0x0a, 0x06, 0x63, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x74, 0x74, 0x70, 0x50, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12, + 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, + 0x6f, 0x64, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, + 0x62, 0x6f, 0x64, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x43, 0x0a, 0x13, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x48, 0x74, 0x74, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x12, 0x61, 0x64, 0x64, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x09, 0x0a, + 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x3b, 0x0a, 0x11, 0x43, 0x75, 0x73, 0x74, + 0x6f, 0x6d, 0x48, 0x74, 0x74, 0x70, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x12, 0x0a, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x4d, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x6e, + 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x65, 0x78, 0x74, 0x5a, 0x2c, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2d, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x70, 0x63, + 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_trpc_api_http_proto_rawDescOnce sync.Once + file_trpc_api_http_proto_rawDescData = file_trpc_api_http_proto_rawDesc +) + +func file_trpc_api_http_proto_rawDescGZIP() []byte { + file_trpc_api_http_proto_rawDescOnce.Do(func() { + file_trpc_api_http_proto_rawDescData = protoimpl.X.CompressGZIP(file_trpc_api_http_proto_rawDescData) + }) + return file_trpc_api_http_proto_rawDescData +} + +var file_trpc_api_http_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_trpc_api_http_proto_goTypes = []interface{}{ + (*HttpRule)(nil), // 0: trpc.api.HttpRule + (*CustomHttpPattern)(nil), // 1: trpc.api.CustomHttpPattern +} +var file_trpc_api_http_proto_depIdxs = []int32{ + 1, // 0: trpc.api.HttpRule.custom:type_name -> trpc.api.CustomHttpPattern + 0, // 1: trpc.api.HttpRule.additional_bindings:type_name -> trpc.api.HttpRule + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_trpc_api_http_proto_init() } +func file_trpc_api_http_proto_init() { + if File_trpc_api_http_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_trpc_api_http_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HttpRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_api_http_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CustomHttpPattern); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_trpc_api_http_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*HttpRule_Get)(nil), + (*HttpRule_Put)(nil), + (*HttpRule_Post)(nil), + (*HttpRule_Delete)(nil), + (*HttpRule_Patch)(nil), + (*HttpRule_Custom)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_api_http_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_trpc_api_http_proto_goTypes, + DependencyIndexes: file_trpc_api_http_proto_depIdxs, + MessageInfos: file_trpc_api_http_proto_msgTypes, + }.Build() + File_trpc_api_http_proto = out.File + file_trpc_api_http_proto_rawDesc = nil + file_trpc_api_http_proto_goTypes = nil + file_trpc_api_http_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/pb/go/trpc/go.mod b/install/submodules/trpc-protocol/pb/go/trpc/go.mod new file mode 100644 index 0000000..d3a0a07 --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/go.mod @@ -0,0 +1,5 @@ +module trpc.group/trpc/trpc-protocol/pb/go/trpc + +go 1.16 + +require google.golang.org/protobuf v1.30.0 diff --git a/install/submodules/trpc-protocol/pb/go/trpc/go.sum b/install/submodules/trpc-protocol/pb/go/trpc/go.sum new file mode 100644 index 0000000..1838366 --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/go.sum @@ -0,0 +1,8 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/install/submodules/trpc-protocol/pb/go/trpc/proto/trpc_options.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/proto/trpc_options.pb.go new file mode 100644 index 0000000..ab6b8b1 --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/proto/trpc_options.pb.go @@ -0,0 +1,113 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/proto/trpc_options.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +var file_trpc_proto_trpc_options_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*string)(nil), + Field: 50001, + Name: "trpc.alias", + Tag: "bytes,50001,opt,name=alias", + Filename: "trpc/proto/trpc_options.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*string)(nil), + Field: 50050, + Name: "trpc.go_tag", + Tag: "bytes,50050,opt,name=go_tag", + Filename: "trpc/proto/trpc_options.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional string alias = 50001; + E_Alias = &file_trpc_proto_trpc_options_proto_extTypes[0] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // optional string go_tag = 50050; + E_GoTag = &file_trpc_proto_trpc_options_proto_extTypes[1] +) + +var File_trpc_proto_trpc_options_proto protoreflect.FileDescriptor + +var file_trpc_proto_trpc_options_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x72, 0x70, + 0x63, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x04, 0x74, 0x72, 0x70, 0x63, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3a, 0x36, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, + 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xd1, 0x86, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x3a, + 0x36, 0x0a, 0x06, 0x67, 0x6f, 0x5f, 0x74, 0x61, 0x67, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x82, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x67, 0x6f, 0x54, 0x61, 0x67, 0x42, 0x4f, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x74, + 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x65, 0x78, 0x74, 0x5a, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2d, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, + 0x70, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_trpc_proto_trpc_options_proto_goTypes = []interface{}{ + (*descriptorpb.MethodOptions)(nil), // 0: google.protobuf.MethodOptions + (*descriptorpb.FieldOptions)(nil), // 1: google.protobuf.FieldOptions +} +var file_trpc_proto_trpc_options_proto_depIdxs = []int32{ + 0, // 0: trpc.alias:extendee -> google.protobuf.MethodOptions + 1, // 1: trpc.go_tag:extendee -> google.protobuf.FieldOptions + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 0, // [0:2] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_trpc_proto_trpc_options_proto_init() } +func file_trpc_proto_trpc_options_proto_init() { + if File_trpc_proto_trpc_options_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_proto_trpc_options_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 2, + NumServices: 0, + }, + GoTypes: file_trpc_proto_trpc_options_proto_goTypes, + DependencyIndexes: file_trpc_proto_trpc_options_proto_depIdxs, + ExtensionInfos: file_trpc_proto_trpc_options_proto_extTypes, + }.Build() + File_trpc_proto_trpc_options_proto = out.File + file_trpc_proto_trpc_options_proto_rawDesc = nil + file_trpc_proto_trpc_options_proto_goTypes = nil + file_trpc_proto_trpc_options_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/pb/go/trpc/swagger/swagger.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/swagger/swagger.pb.go new file mode 100644 index 0000000..c81c771 --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/swagger/swagger.pb.go @@ -0,0 +1,290 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/swagger/swagger.proto + +package swagger + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// to gen swagger json +type SwaggerRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title string `protobuf:"bytes,50103,opt,name=title,proto3" json:"title,omitempty"` + Method string `protobuf:"bytes,50104,opt,name=method,proto3" json:"method,omitempty"` + Description string `protobuf:"bytes,50105,opt,name=description,proto3" json:"description,omitempty"` + Params []*SwaggerParam `protobuf:"bytes,50106,rep,name=params,proto3" json:"params,omitempty"` +} + +func (x *SwaggerRule) Reset() { + *x = SwaggerRule{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_swagger_swagger_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SwaggerRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwaggerRule) ProtoMessage() {} + +func (x *SwaggerRule) ProtoReflect() protoreflect.Message { + mi := &file_trpc_swagger_swagger_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SwaggerRule.ProtoReflect.Descriptor instead. +func (*SwaggerRule) Descriptor() ([]byte, []int) { + return file_trpc_swagger_swagger_proto_rawDescGZIP(), []int{0} +} + +func (x *SwaggerRule) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *SwaggerRule) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +func (x *SwaggerRule) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *SwaggerRule) GetParams() []*SwaggerParam { + if x != nil { + return x.Params + } + return nil +} + +type SwaggerParam struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` + Default string `protobuf:"bytes,3,opt,name=default,proto3" json:"default,omitempty"` +} + +func (x *SwaggerParam) Reset() { + *x = SwaggerParam{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_swagger_swagger_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SwaggerParam) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SwaggerParam) ProtoMessage() {} + +func (x *SwaggerParam) ProtoReflect() protoreflect.Message { + mi := &file_trpc_swagger_swagger_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SwaggerParam.ProtoReflect.Descriptor instead. +func (*SwaggerParam) Descriptor() ([]byte, []int) { + return file_trpc_swagger_swagger_proto_rawDescGZIP(), []int{1} +} + +func (x *SwaggerParam) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SwaggerParam) GetRequired() bool { + if x != nil { + return x.Required + } + return false +} + +func (x *SwaggerParam) GetDefault() string { + if x != nil { + return x.Default + } + return "" +} + +var file_trpc_swagger_swagger_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MethodOptions)(nil), + ExtensionType: (*SwaggerRule)(nil), + Field: 50101, + Name: "trpc.swagger", + Tag: "bytes,50101,opt,name=swagger", + Filename: "trpc/swagger/swagger.proto", + }, +} + +// Extension fields to descriptorpb.MethodOptions. +var ( + // optional trpc.SwaggerRule swagger = 50101; + E_Swagger = &file_trpc_swagger_swagger_proto_extTypes[0] +) + +var File_trpc_swagger_swagger_proto protoreflect.FileDescriptor + +var file_trpc_swagger_swagger_proto_rawDesc = []byte{ + 0x0a, 0x1a, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x73, + 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x74, 0x72, + 0x70, 0x63, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x91, 0x01, 0x0a, 0x0b, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, + 0x52, 0x75, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0xb7, 0x87, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0xb8, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x22, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0xb9, 0x87, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x18, 0xba, 0x87, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x58, 0x0a, 0x0c, 0x53, 0x77, 0x61, 0x67, + 0x67, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, + 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x3a, 0x4d, 0x0a, 0x07, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, 0x72, 0x12, 0x1e, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb5, 0x87, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x77, 0x61, + 0x67, 0x67, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65, + 0x72, 0x42, 0x51, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x74, + 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x65, + 0x78, 0x74, 0x5a, 0x30, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2f, 0x74, + 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x77, 0x61, + 0x67, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_trpc_swagger_swagger_proto_rawDescOnce sync.Once + file_trpc_swagger_swagger_proto_rawDescData = file_trpc_swagger_swagger_proto_rawDesc +) + +func file_trpc_swagger_swagger_proto_rawDescGZIP() []byte { + file_trpc_swagger_swagger_proto_rawDescOnce.Do(func() { + file_trpc_swagger_swagger_proto_rawDescData = protoimpl.X.CompressGZIP(file_trpc_swagger_swagger_proto_rawDescData) + }) + return file_trpc_swagger_swagger_proto_rawDescData +} + +var file_trpc_swagger_swagger_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_trpc_swagger_swagger_proto_goTypes = []interface{}{ + (*SwaggerRule)(nil), // 0: trpc.SwaggerRule + (*SwaggerParam)(nil), // 1: trpc.SwaggerParam + (*descriptorpb.MethodOptions)(nil), // 2: google.protobuf.MethodOptions +} +var file_trpc_swagger_swagger_proto_depIdxs = []int32{ + 1, // 0: trpc.SwaggerRule.params:type_name -> trpc.SwaggerParam + 2, // 1: trpc.swagger:extendee -> google.protobuf.MethodOptions + 0, // 2: trpc.swagger:type_name -> trpc.SwaggerRule + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 2, // [2:3] is the sub-list for extension type_name + 1, // [1:2] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_trpc_swagger_swagger_proto_init() } +func file_trpc_swagger_swagger_proto_init() { + if File_trpc_swagger_swagger_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_trpc_swagger_swagger_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SwaggerRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_swagger_swagger_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SwaggerParam); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_swagger_swagger_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_trpc_swagger_swagger_proto_goTypes, + DependencyIndexes: file_trpc_swagger_swagger_proto_depIdxs, + MessageInfos: file_trpc_swagger_swagger_proto_msgTypes, + ExtensionInfos: file_trpc_swagger_swagger_proto_extTypes, + }.Build() + File_trpc_swagger_swagger_proto = out.File + file_trpc_swagger_swagger_proto_rawDesc = nil + file_trpc_swagger_swagger_proto_goTypes = nil + file_trpc_swagger_swagger_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/pb/go/trpc/trpc.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/trpc.pb.go new file mode 100644 index 0000000..49ce62e --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/trpc.pb.go @@ -0,0 +1,1970 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/trpc.proto + +package trpc + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// 框架协议头里的魔数 +type TrpcMagic int32 + +const ( + // trpc不用这个值,为了提供给pb工具生成代码 + TrpcMagic_TRPC_DEFAULT_NONE TrpcMagic = 0 + // trpc协议默认使用这个魔数 + TrpcMagic_TRPC_MAGIC_VALUE TrpcMagic = 2352 +) + +// Enum value maps for TrpcMagic. +var ( + TrpcMagic_name = map[int32]string{ + 0: "TRPC_DEFAULT_NONE", + 2352: "TRPC_MAGIC_VALUE", + } + TrpcMagic_value = map[string]int32{ + "TRPC_DEFAULT_NONE": 0, + "TRPC_MAGIC_VALUE": 2352, + } +) + +func (x TrpcMagic) Enum() *TrpcMagic { + p := new(TrpcMagic) + *p = x + return p +} + +func (x TrpcMagic) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcMagic) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[0].Descriptor() +} + +func (TrpcMagic) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[0] +} + +func (x TrpcMagic) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcMagic.Descriptor instead. +func (TrpcMagic) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{0} +} + +// trpc协议的二进制数据帧类型 +// 目前支持两种类型的二进制数据帧: +// 1. 一应一答模式的二进制数据帧类型 +// 2. 流式模式的二进制数据帧类型 +type TrpcDataFrameType int32 + +const ( + // trpc一应一答模式的二进制数据帧类型 + TrpcDataFrameType_TRPC_UNARY_FRAME TrpcDataFrameType = 0 + // trpc流式模式的二进制数据帧类型 + TrpcDataFrameType_TRPC_STREAM_FRAME TrpcDataFrameType = 1 +) + +// Enum value maps for TrpcDataFrameType. +var ( + TrpcDataFrameType_name = map[int32]string{ + 0: "TRPC_UNARY_FRAME", + 1: "TRPC_STREAM_FRAME", + } + TrpcDataFrameType_value = map[string]int32{ + "TRPC_UNARY_FRAME": 0, + "TRPC_STREAM_FRAME": 1, + } +) + +func (x TrpcDataFrameType) Enum() *TrpcDataFrameType { + p := new(TrpcDataFrameType) + *p = x + return p +} + +func (x TrpcDataFrameType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcDataFrameType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[1].Descriptor() +} + +func (TrpcDataFrameType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[1] +} + +func (x TrpcDataFrameType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcDataFrameType.Descriptor instead. +func (TrpcDataFrameType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{1} +} + +// trpc协议流式的二进制数据帧类型 +// 目前流式帧类型分4种:INIT/DATA/FEEDBACK/CLOSE,其中CLOSE帧不带业务数据 +// INIT帧:FIXHEADER + TrpcStreamInitMeta +// DATA帧:FIXHEADER + body(业务序列化的数据) +// FEEDBACK帧:FIXHEADER + TrpcStreamFeedBackMeta(触发策略,高低水位+定时) +// CLOSE帧:FIXHEADER + TrpcStreamCloseMeta +// 连接和流空闲超时的回收机制不考虑 +type TrpcStreamFrameType int32 + +const ( + // 一应一答的默认取值 + TrpcStreamFrameType_TRPC_UNARY TrpcStreamFrameType = 0 + // 流式INIT帧类型 + TrpcStreamFrameType_TRPC_STREAM_FRAME_INIT TrpcStreamFrameType = 1 + // 流式DATA帧类型 + TrpcStreamFrameType_TRPC_STREAM_FRAME_DATA TrpcStreamFrameType = 2 + // 流式FEEDBACK帧类型 + TrpcStreamFrameType_TRPC_STREAM_FRAME_FEEDBACK TrpcStreamFrameType = 3 + // 流式CLOSE帧类型 + TrpcStreamFrameType_TRPC_STREAM_FRAME_CLOSE TrpcStreamFrameType = 4 +) + +// Enum value maps for TrpcStreamFrameType. +var ( + TrpcStreamFrameType_name = map[int32]string{ + 0: "TRPC_UNARY", + 1: "TRPC_STREAM_FRAME_INIT", + 2: "TRPC_STREAM_FRAME_DATA", + 3: "TRPC_STREAM_FRAME_FEEDBACK", + 4: "TRPC_STREAM_FRAME_CLOSE", + } + TrpcStreamFrameType_value = map[string]int32{ + "TRPC_UNARY": 0, + "TRPC_STREAM_FRAME_INIT": 1, + "TRPC_STREAM_FRAME_DATA": 2, + "TRPC_STREAM_FRAME_FEEDBACK": 3, + "TRPC_STREAM_FRAME_CLOSE": 4, + } +) + +func (x TrpcStreamFrameType) Enum() *TrpcStreamFrameType { + p := new(TrpcStreamFrameType) + *p = x + return p +} + +func (x TrpcStreamFrameType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcStreamFrameType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[2].Descriptor() +} + +func (TrpcStreamFrameType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[2] +} + +func (x TrpcStreamFrameType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcStreamFrameType.Descriptor instead. +func (TrpcStreamFrameType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{2} +} + +// trpc流式关闭类型 +type TrpcStreamCloseType int32 + +const ( + // 正常单向流关闭 + TrpcStreamCloseType_TRPC_STREAM_CLOSE TrpcStreamCloseType = 0 + // 异常关闭双向流 + TrpcStreamCloseType_TRPC_STREAM_RESET TrpcStreamCloseType = 1 +) + +// Enum value maps for TrpcStreamCloseType. +var ( + TrpcStreamCloseType_name = map[int32]string{ + 0: "TRPC_STREAM_CLOSE", + 1: "TRPC_STREAM_RESET", + } + TrpcStreamCloseType_value = map[string]int32{ + "TRPC_STREAM_CLOSE": 0, + "TRPC_STREAM_RESET": 1, + } +) + +func (x TrpcStreamCloseType) Enum() *TrpcStreamCloseType { + p := new(TrpcStreamCloseType) + *p = x + return p +} + +func (x TrpcStreamCloseType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcStreamCloseType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[3].Descriptor() +} + +func (TrpcStreamCloseType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[3] +} + +func (x TrpcStreamCloseType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcStreamCloseType.Descriptor instead. +func (TrpcStreamCloseType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{3} +} + +// trpc协议版本 +type TrpcProtoVersion int32 + +const ( + // 默认版本 + TrpcProtoVersion_TRPC_PROTO_V1 TrpcProtoVersion = 0 +) + +// Enum value maps for TrpcProtoVersion. +var ( + TrpcProtoVersion_name = map[int32]string{ + 0: "TRPC_PROTO_V1", + } + TrpcProtoVersion_value = map[string]int32{ + "TRPC_PROTO_V1": 0, + } +) + +func (x TrpcProtoVersion) Enum() *TrpcProtoVersion { + p := new(TrpcProtoVersion) + *p = x + return p +} + +func (x TrpcProtoVersion) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcProtoVersion) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[4].Descriptor() +} + +func (TrpcProtoVersion) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[4] +} + +func (x TrpcProtoVersion) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcProtoVersion.Descriptor instead. +func (TrpcProtoVersion) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{4} +} + +// trpc协议中的调用类型 +type TrpcCallType int32 + +const ( + // 一应一答调用,包括同步、异步 + TrpcCallType_TRPC_UNARY_CALL TrpcCallType = 0 + // 单向调用 + TrpcCallType_TRPC_ONEWAY_CALL TrpcCallType = 1 +) + +// Enum value maps for TrpcCallType. +var ( + TrpcCallType_name = map[int32]string{ + 0: "TRPC_UNARY_CALL", + 1: "TRPC_ONEWAY_CALL", + } + TrpcCallType_value = map[string]int32{ + "TRPC_UNARY_CALL": 0, + "TRPC_ONEWAY_CALL": 1, + } +) + +func (x TrpcCallType) Enum() *TrpcCallType { + p := new(TrpcCallType) + *p = x + return p +} + +func (x TrpcCallType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcCallType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[5].Descriptor() +} + +func (TrpcCallType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[5] +} + +func (x TrpcCallType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcCallType.Descriptor instead. +func (TrpcCallType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{5} +} + +// trpc协议中的消息透传支持的类型 +type TrpcMessageType int32 + +const ( + // trpc 不用这个值,为了提供给 pb 工具生成代码 + TrpcMessageType_TRPC_DEFAULT TrpcMessageType = 0 + // 染色 + TrpcMessageType_TRPC_DYEING_MESSAGE TrpcMessageType = 1 + // 调用链 + TrpcMessageType_TRPC_TRACE_MESSAGE TrpcMessageType = 2 + // 多环境 + TrpcMessageType_TRPC_MULTI_ENV_MESSAGE TrpcMessageType = 4 + // 灰度 + TrpcMessageType_TRPC_GRID_MESSAGE TrpcMessageType = 8 + // set名 + TrpcMessageType_TRPC_SETNAME_MESSAGE TrpcMessageType = 16 +) + +// Enum value maps for TrpcMessageType. +var ( + TrpcMessageType_name = map[int32]string{ + 0: "TRPC_DEFAULT", + 1: "TRPC_DYEING_MESSAGE", + 2: "TRPC_TRACE_MESSAGE", + 4: "TRPC_MULTI_ENV_MESSAGE", + 8: "TRPC_GRID_MESSAGE", + 16: "TRPC_SETNAME_MESSAGE", + } + TrpcMessageType_value = map[string]int32{ + "TRPC_DEFAULT": 0, + "TRPC_DYEING_MESSAGE": 1, + "TRPC_TRACE_MESSAGE": 2, + "TRPC_MULTI_ENV_MESSAGE": 4, + "TRPC_GRID_MESSAGE": 8, + "TRPC_SETNAME_MESSAGE": 16, + } +) + +func (x TrpcMessageType) Enum() *TrpcMessageType { + p := new(TrpcMessageType) + *p = x + return p +} + +func (x TrpcMessageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcMessageType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[6].Descriptor() +} + +func (TrpcMessageType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[6] +} + +func (x TrpcMessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcMessageType.Descriptor instead. +func (TrpcMessageType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{6} +} + +// trpc协议中 data 内容的编码类型 +// 默认使用pb +// 目前约定 0-127 范围的取值为框架规范的序列化方式,框架使用 +type TrpcContentEncodeType int32 + +const ( + // pb + TrpcContentEncodeType_TRPC_PROTO_ENCODE TrpcContentEncodeType = 0 + // jce + TrpcContentEncodeType_TRPC_JCE_ENCODE TrpcContentEncodeType = 1 + // json + TrpcContentEncodeType_TRPC_JSON_ENCODE TrpcContentEncodeType = 2 + // flatbuffer + TrpcContentEncodeType_TRPC_FLATBUFFER_ENCODE TrpcContentEncodeType = 3 + // 不序列化 + TrpcContentEncodeType_TRPC_NOOP_ENCODE TrpcContentEncodeType = 4 + // xml + TrpcContentEncodeType_TRPC_XML_ENCODE TrpcContentEncodeType = 5 + // thrift + TrpcContentEncodeType_TRPC_THRIFT_ENCODE TrpcContentEncodeType = 6 +) + +// Enum value maps for TrpcContentEncodeType. +var ( + TrpcContentEncodeType_name = map[int32]string{ + 0: "TRPC_PROTO_ENCODE", + 1: "TRPC_JCE_ENCODE", + 2: "TRPC_JSON_ENCODE", + 3: "TRPC_FLATBUFFER_ENCODE", + 4: "TRPC_NOOP_ENCODE", + 5: "TRPC_XML_ENCODE", + 6: "TRPC_THRIFT_ENCODE", + } + TrpcContentEncodeType_value = map[string]int32{ + "TRPC_PROTO_ENCODE": 0, + "TRPC_JCE_ENCODE": 1, + "TRPC_JSON_ENCODE": 2, + "TRPC_FLATBUFFER_ENCODE": 3, + "TRPC_NOOP_ENCODE": 4, + "TRPC_XML_ENCODE": 5, + "TRPC_THRIFT_ENCODE": 6, + } +) + +func (x TrpcContentEncodeType) Enum() *TrpcContentEncodeType { + p := new(TrpcContentEncodeType) + *p = x + return p +} + +func (x TrpcContentEncodeType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcContentEncodeType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[7].Descriptor() +} + +func (TrpcContentEncodeType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[7] +} + +func (x TrpcContentEncodeType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcContentEncodeType.Descriptor instead. +func (TrpcContentEncodeType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{7} +} + +// trpc协议中 data 内容的压缩类型 +// 默认使用不压缩 +type TrpcCompressType int32 + +const ( + // 默认不使用压缩 + TrpcCompressType_TRPC_DEFAULT_COMPRESS TrpcCompressType = 0 + // 使用gzip + TrpcCompressType_TRPC_GZIP_COMPRESS TrpcCompressType = 1 + // 使用snappy + // + // Deprecated: 建议使用 TRPC_SNAPPY_STREAM_COMPRESS/TRPC_SNAPPY_BLOCK_COMPRESS, 因为现在 + // trpc-go 和 trpc-cpp 分别的使用的是 stream、block 模式,二者不兼容,跨语言调用会出错 + TrpcCompressType_TRPC_SNAPPY_COMPRESS TrpcCompressType = 2 + // 使用zlib + TrpcCompressType_TRPC_ZLIB_COMPRESS TrpcCompressType = 3 + // 使用 stream 模式的 snappy + TrpcCompressType_TRPC_SNAPPY_STREAM_COMPRESS TrpcCompressType = 4 + // 使用 block 模式的 snappy + TrpcCompressType_TRPC_SNAPPY_BLOCK_COMPRESS TrpcCompressType = 5 + // 使用 frame 模式的 lz4 + TrpcCompressType_TRPC_LZ4_FRAME_COMPRESS TrpcCompressType = 6 + // 使用 block 模式的 lz4 + TrpcCompressType_TRPC_LZ4_BLOCK_COMPRESS TrpcCompressType = 7 +) + +// Enum value maps for TrpcCompressType. +var ( + TrpcCompressType_name = map[int32]string{ + 0: "TRPC_DEFAULT_COMPRESS", + 1: "TRPC_GZIP_COMPRESS", + 2: "TRPC_SNAPPY_COMPRESS", + 3: "TRPC_ZLIB_COMPRESS", + 4: "TRPC_SNAPPY_STREAM_COMPRESS", + 5: "TRPC_SNAPPY_BLOCK_COMPRESS", + 6: "TRPC_LZ4_FRAME_COMPRESS", + 7: "TRPC_LZ4_BLOCK_COMPRESS", + } + TrpcCompressType_value = map[string]int32{ + "TRPC_DEFAULT_COMPRESS": 0, + "TRPC_GZIP_COMPRESS": 1, + "TRPC_SNAPPY_COMPRESS": 2, + "TRPC_ZLIB_COMPRESS": 3, + "TRPC_SNAPPY_STREAM_COMPRESS": 4, + "TRPC_SNAPPY_BLOCK_COMPRESS": 5, + "TRPC_LZ4_FRAME_COMPRESS": 6, + "TRPC_LZ4_BLOCK_COMPRESS": 7, + } +) + +func (x TrpcCompressType) Enum() *TrpcCompressType { + p := new(TrpcCompressType) + *p = x + return p +} + +func (x TrpcCompressType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcCompressType) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[8].Descriptor() +} + +func (TrpcCompressType) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[8] +} + +func (x TrpcCompressType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcCompressType.Descriptor instead. +func (TrpcCompressType) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{8} +} + +// 框架层接口调用的返回码定义 +type TrpcRetCode int32 + +const ( + // 调用成功 + TrpcRetCode_TRPC_INVOKE_SUCCESS TrpcRetCode = 0 + // 协议错误码 + // 服务端解码错误 + TrpcRetCode_TRPC_SERVER_DECODE_ERR TrpcRetCode = 1 + // 服务端编码错误 + TrpcRetCode_TRPC_SERVER_ENCODE_ERR TrpcRetCode = 2 + // service或者func路由错误码 + // 服务端没有调用相应的service实现 + TrpcRetCode_TRPC_SERVER_NOSERVICE_ERR TrpcRetCode = 11 + // 服务端没有调用相应的接口实现 + TrpcRetCode_TRPC_SERVER_NOFUNC_ERR TrpcRetCode = 12 + // 超时/过载/限流错误码 + // 请求在服务端超时 + TrpcRetCode_TRPC_SERVER_TIMEOUT_ERR TrpcRetCode = 21 + // 请求在服务端被过载保护而丢弃请求 + // 主要用在框架内部实现的过载保护插件上 + TrpcRetCode_TRPC_SERVER_OVERLOAD_ERR TrpcRetCode = 22 + // 请求在服务端被限流 + // 主要用在外部服务治理系统的插件或者业务自定义的限流插件上,比如: 北极星限流 + TrpcRetCode_TRPC_SERVER_LIMITED_ERR TrpcRetCode = 23 + // 请求在服务端因全链路超时时间而超时 + TrpcRetCode_TRPC_SERVER_FULL_LINK_TIMEOUT_ERR TrpcRetCode = 24 + // 服务端系统错误 + TrpcRetCode_TRPC_SERVER_SYSTEM_ERR TrpcRetCode = 31 + // 服务端鉴权失败错误 + TrpcRetCode_TRPC_SERVER_AUTH_ERR TrpcRetCode = 41 + // 服务端请求参数自动校验失败错误 + TrpcRetCode_TRPC_SERVER_VALIDATE_ERR TrpcRetCode = 51 + // 超时错误码 + // 请求在客户端调用超时 + TrpcRetCode_TRPC_CLIENT_INVOKE_TIMEOUT_ERR TrpcRetCode = 101 + // 请求在客户端因全链路超时时间而超时 + TrpcRetCode_TRPC_CLIENT_FULL_LINK_TIMEOUT_ERR TrpcRetCode = 102 + // 网络相关错误码 + // 客户端连接错误 + TrpcRetCode_TRPC_CLIENT_CONNECT_ERR TrpcRetCode = 111 + // 协议相关错误码 + // 客户端编码错误 + TrpcRetCode_TRPC_CLIENT_ENCODE_ERR TrpcRetCode = 121 + // 客户端解码错误 + TrpcRetCode_TRPC_CLIENT_DECODE_ERR TrpcRetCode = 122 + // 过载保护/限流相关错误码 + // 请求在客户端被限流 + // 主要用在外部服务治理系统的插件或者业务自定义的限流插件上,比如: 北极星限流 + TrpcRetCode_TRPC_CLIENT_LIMITED_ERR TrpcRetCode = 123 + // 请求在客户端被过载保护而丢弃请求 + // 主要用在框架内部实现的过载保护插件上 + TrpcRetCode_TRPC_CLIENT_OVERLOAD_ERR TrpcRetCode = 124 + // 路由相关错误码 + // 客户端选ip路由错误 + TrpcRetCode_TRPC_CLIENT_ROUTER_ERR TrpcRetCode = 131 + // 客户端网络错误 + TrpcRetCode_TRPC_CLIENT_NETWORK_ERR TrpcRetCode = 141 + // 客户端响应参数自动校验失败错误 + TrpcRetCode_TRPC_CLIENT_VALIDATE_ERR TrpcRetCode = 151 + // 上游主动断开连接,提前取消请求错误 + TrpcRetCode_TRPC_CLIENT_CANCELED_ERR TrpcRetCode = 161 + // 客户端读取 Frame 错误 + TrpcRetCode_TRPC_CLIENT_READ_FRAME_ERR TrpcRetCode = 171 + // 服务端流式网络错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_SERVER_NETWORK_ERR TrpcRetCode = 201 + // 服务端流式传输错误, 详细错误码需要在实现过程中再梳理 + // 比如:流消息过大等 + TrpcRetCode_TRPC_STREAM_SERVER_MSG_EXCEED_LIMIT_ERR TrpcRetCode = 211 + // 服务端流式编码错误 + TrpcRetCode_TRPC_STREAM_SERVER_ENCODE_ERR TrpcRetCode = 221 + // 客户端流式编解码错误 + TrpcRetCode_TRPC_STREAM_SERVER_DECODE_ERR TrpcRetCode = 222 + // 服务端流式写错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_SERVER_WRITE_END TrpcRetCode = 231 + TrpcRetCode_TRPC_STREAM_SERVER_WRITE_OVERFLOW_ERR TrpcRetCode = 232 + TrpcRetCode_TRPC_STREAM_SERVER_WRITE_CLOSE_ERR TrpcRetCode = 233 + TrpcRetCode_TRPC_STREAM_SERVER_WRITE_TIMEOUT_ERR TrpcRetCode = 234 + // 服务端流式读错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_SERVER_READ_END TrpcRetCode = 251 + TrpcRetCode_TRPC_STREAM_SERVER_READ_CLOSE_ERR TrpcRetCode = 252 + TrpcRetCode_TRPC_STREAM_SERVER_READ_EMPTY_ERR TrpcRetCode = 253 + TrpcRetCode_TRPC_STREAM_SERVER_READ_TIMEOUT_ERR TrpcRetCode = 254 + // 客户端流式网络错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_CLIENT_NETWORK_ERR TrpcRetCode = 301 + // 客户端流式传输错误, 详细错误码需要在实现过程中再梳理 + // 比如:流消息过大等 + TrpcRetCode_TRPC_STREAM_CLIENT_MSG_EXCEED_LIMIT_ERR TrpcRetCode = 311 + // 客户端流式编码错误 + TrpcRetCode_TRPC_STREAM_CLIENT_ENCODE_ERR TrpcRetCode = 321 + // 客户端流式编解码错误 + TrpcRetCode_TRPC_STREAM_CLIENT_DECODE_ERR TrpcRetCode = 322 + // 客户端流式写错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_CLIENT_WRITE_END TrpcRetCode = 331 + TrpcRetCode_TRPC_STREAM_CLIENT_WRITE_OVERFLOW_ERR TrpcRetCode = 332 + TrpcRetCode_TRPC_STREAM_CLIENT_WRITE_CLOSE_ERR TrpcRetCode = 333 + TrpcRetCode_TRPC_STREAM_CLIENT_WRITE_TIMEOUT_ERR TrpcRetCode = 334 + // 客户端流式读错误, 详细错误码需要在实现过程中再梳理 + TrpcRetCode_TRPC_STREAM_CLIENT_READ_END TrpcRetCode = 351 + TrpcRetCode_TRPC_STREAM_CLIENT_READ_CLOSE_ERR TrpcRetCode = 352 + TrpcRetCode_TRPC_STREAM_CLIENT_READ_EMPTY_ERR TrpcRetCode = 353 + TrpcRetCode_TRPC_STREAM_CLIENT_READ_TIMEOUT_ERR TrpcRetCode = 354 + // 未明确的错误 + TrpcRetCode_TRPC_INVOKE_UNKNOWN_ERR TrpcRetCode = 999 + // 未明确的错误 + TrpcRetCode_TRPC_STREAM_UNKNOWN_ERR TrpcRetCode = 1000 +) + +// Enum value maps for TrpcRetCode. +var ( + TrpcRetCode_name = map[int32]string{ + 0: "TRPC_INVOKE_SUCCESS", + 1: "TRPC_SERVER_DECODE_ERR", + 2: "TRPC_SERVER_ENCODE_ERR", + 11: "TRPC_SERVER_NOSERVICE_ERR", + 12: "TRPC_SERVER_NOFUNC_ERR", + 21: "TRPC_SERVER_TIMEOUT_ERR", + 22: "TRPC_SERVER_OVERLOAD_ERR", + 23: "TRPC_SERVER_LIMITED_ERR", + 24: "TRPC_SERVER_FULL_LINK_TIMEOUT_ERR", + 31: "TRPC_SERVER_SYSTEM_ERR", + 41: "TRPC_SERVER_AUTH_ERR", + 51: "TRPC_SERVER_VALIDATE_ERR", + 101: "TRPC_CLIENT_INVOKE_TIMEOUT_ERR", + 102: "TRPC_CLIENT_FULL_LINK_TIMEOUT_ERR", + 111: "TRPC_CLIENT_CONNECT_ERR", + 121: "TRPC_CLIENT_ENCODE_ERR", + 122: "TRPC_CLIENT_DECODE_ERR", + 123: "TRPC_CLIENT_LIMITED_ERR", + 124: "TRPC_CLIENT_OVERLOAD_ERR", + 131: "TRPC_CLIENT_ROUTER_ERR", + 141: "TRPC_CLIENT_NETWORK_ERR", + 151: "TRPC_CLIENT_VALIDATE_ERR", + 161: "TRPC_CLIENT_CANCELED_ERR", + 171: "TRPC_CLIENT_READ_FRAME_ERR", + 201: "TRPC_STREAM_SERVER_NETWORK_ERR", + 211: "TRPC_STREAM_SERVER_MSG_EXCEED_LIMIT_ERR", + 221: "TRPC_STREAM_SERVER_ENCODE_ERR", + 222: "TRPC_STREAM_SERVER_DECODE_ERR", + 231: "TRPC_STREAM_SERVER_WRITE_END", + 232: "TRPC_STREAM_SERVER_WRITE_OVERFLOW_ERR", + 233: "TRPC_STREAM_SERVER_WRITE_CLOSE_ERR", + 234: "TRPC_STREAM_SERVER_WRITE_TIMEOUT_ERR", + 251: "TRPC_STREAM_SERVER_READ_END", + 252: "TRPC_STREAM_SERVER_READ_CLOSE_ERR", + 253: "TRPC_STREAM_SERVER_READ_EMPTY_ERR", + 254: "TRPC_STREAM_SERVER_READ_TIMEOUT_ERR", + 301: "TRPC_STREAM_CLIENT_NETWORK_ERR", + 311: "TRPC_STREAM_CLIENT_MSG_EXCEED_LIMIT_ERR", + 321: "TRPC_STREAM_CLIENT_ENCODE_ERR", + 322: "TRPC_STREAM_CLIENT_DECODE_ERR", + 331: "TRPC_STREAM_CLIENT_WRITE_END", + 332: "TRPC_STREAM_CLIENT_WRITE_OVERFLOW_ERR", + 333: "TRPC_STREAM_CLIENT_WRITE_CLOSE_ERR", + 334: "TRPC_STREAM_CLIENT_WRITE_TIMEOUT_ERR", + 351: "TRPC_STREAM_CLIENT_READ_END", + 352: "TRPC_STREAM_CLIENT_READ_CLOSE_ERR", + 353: "TRPC_STREAM_CLIENT_READ_EMPTY_ERR", + 354: "TRPC_STREAM_CLIENT_READ_TIMEOUT_ERR", + 999: "TRPC_INVOKE_UNKNOWN_ERR", + 1000: "TRPC_STREAM_UNKNOWN_ERR", + } + TrpcRetCode_value = map[string]int32{ + "TRPC_INVOKE_SUCCESS": 0, + "TRPC_SERVER_DECODE_ERR": 1, + "TRPC_SERVER_ENCODE_ERR": 2, + "TRPC_SERVER_NOSERVICE_ERR": 11, + "TRPC_SERVER_NOFUNC_ERR": 12, + "TRPC_SERVER_TIMEOUT_ERR": 21, + "TRPC_SERVER_OVERLOAD_ERR": 22, + "TRPC_SERVER_LIMITED_ERR": 23, + "TRPC_SERVER_FULL_LINK_TIMEOUT_ERR": 24, + "TRPC_SERVER_SYSTEM_ERR": 31, + "TRPC_SERVER_AUTH_ERR": 41, + "TRPC_SERVER_VALIDATE_ERR": 51, + "TRPC_CLIENT_INVOKE_TIMEOUT_ERR": 101, + "TRPC_CLIENT_FULL_LINK_TIMEOUT_ERR": 102, + "TRPC_CLIENT_CONNECT_ERR": 111, + "TRPC_CLIENT_ENCODE_ERR": 121, + "TRPC_CLIENT_DECODE_ERR": 122, + "TRPC_CLIENT_LIMITED_ERR": 123, + "TRPC_CLIENT_OVERLOAD_ERR": 124, + "TRPC_CLIENT_ROUTER_ERR": 131, + "TRPC_CLIENT_NETWORK_ERR": 141, + "TRPC_CLIENT_VALIDATE_ERR": 151, + "TRPC_CLIENT_CANCELED_ERR": 161, + "TRPC_CLIENT_READ_FRAME_ERR": 171, + "TRPC_STREAM_SERVER_NETWORK_ERR": 201, + "TRPC_STREAM_SERVER_MSG_EXCEED_LIMIT_ERR": 211, + "TRPC_STREAM_SERVER_ENCODE_ERR": 221, + "TRPC_STREAM_SERVER_DECODE_ERR": 222, + "TRPC_STREAM_SERVER_WRITE_END": 231, + "TRPC_STREAM_SERVER_WRITE_OVERFLOW_ERR": 232, + "TRPC_STREAM_SERVER_WRITE_CLOSE_ERR": 233, + "TRPC_STREAM_SERVER_WRITE_TIMEOUT_ERR": 234, + "TRPC_STREAM_SERVER_READ_END": 251, + "TRPC_STREAM_SERVER_READ_CLOSE_ERR": 252, + "TRPC_STREAM_SERVER_READ_EMPTY_ERR": 253, + "TRPC_STREAM_SERVER_READ_TIMEOUT_ERR": 254, + "TRPC_STREAM_CLIENT_NETWORK_ERR": 301, + "TRPC_STREAM_CLIENT_MSG_EXCEED_LIMIT_ERR": 311, + "TRPC_STREAM_CLIENT_ENCODE_ERR": 321, + "TRPC_STREAM_CLIENT_DECODE_ERR": 322, + "TRPC_STREAM_CLIENT_WRITE_END": 331, + "TRPC_STREAM_CLIENT_WRITE_OVERFLOW_ERR": 332, + "TRPC_STREAM_CLIENT_WRITE_CLOSE_ERR": 333, + "TRPC_STREAM_CLIENT_WRITE_TIMEOUT_ERR": 334, + "TRPC_STREAM_CLIENT_READ_END": 351, + "TRPC_STREAM_CLIENT_READ_CLOSE_ERR": 352, + "TRPC_STREAM_CLIENT_READ_EMPTY_ERR": 353, + "TRPC_STREAM_CLIENT_READ_TIMEOUT_ERR": 354, + "TRPC_INVOKE_UNKNOWN_ERR": 999, + "TRPC_STREAM_UNKNOWN_ERR": 1000, + } +) + +func (x TrpcRetCode) Enum() *TrpcRetCode { + p := new(TrpcRetCode) + *p = x + return p +} + +func (x TrpcRetCode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (TrpcRetCode) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_trpc_proto_enumTypes[9].Descriptor() +} + +func (TrpcRetCode) Type() protoreflect.EnumType { + return &file_trpc_trpc_proto_enumTypes[9] +} + +func (x TrpcRetCode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use TrpcRetCode.Descriptor instead. +func (TrpcRetCode) EnumDescriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{9} +} + +// trpc流式的流控帧头消息定义 +type TrpcStreamInitMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // init请求元信息 + RequestMeta *TrpcStreamInitRequestMeta `protobuf:"bytes,1,opt,name=request_meta,json=requestMeta,proto3" json:"request_meta,omitempty"` + // init响应元信息 + ResponseMeta *TrpcStreamInitResponseMeta `protobuf:"bytes,2,opt,name=response_meta,json=responseMeta,proto3" json:"response_meta,omitempty"` + // 由接收端告知发送端初始的发送窗口大小 + InitWindowSize uint32 `protobuf:"varint,3,opt,name=init_window_size,json=initWindowSize,proto3" json:"init_window_size,omitempty"` + // 请求数据的序列化类型 + // 比如: proto/jce/json, 默认proto + // 具体值与TrpcContentEncodeType对应 + ContentType uint32 `protobuf:"varint,4,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // 请求数据使用的压缩方式 + // 比如: gzip/snappy/..., 默认不使用 + // 具体值与TrpcCompressType对应 + ContentEncoding uint32 `protobuf:"varint,5,opt,name=content_encoding,json=contentEncoding,proto3" json:"content_encoding,omitempty"` +} + +func (x *TrpcStreamInitMeta) Reset() { + *x = TrpcStreamInitMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrpcStreamInitMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrpcStreamInitMeta) ProtoMessage() {} + +func (x *TrpcStreamInitMeta) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrpcStreamInitMeta.ProtoReflect.Descriptor instead. +func (*TrpcStreamInitMeta) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{0} +} + +func (x *TrpcStreamInitMeta) GetRequestMeta() *TrpcStreamInitRequestMeta { + if x != nil { + return x.RequestMeta + } + return nil +} + +func (x *TrpcStreamInitMeta) GetResponseMeta() *TrpcStreamInitResponseMeta { + if x != nil { + return x.ResponseMeta + } + return nil +} + +func (x *TrpcStreamInitMeta) GetInitWindowSize() uint32 { + if x != nil { + return x.InitWindowSize + } + return 0 +} + +func (x *TrpcStreamInitMeta) GetContentType() uint32 { + if x != nil { + return x.ContentType + } + return 0 +} + +func (x *TrpcStreamInitMeta) GetContentEncoding() uint32 { + if x != nil { + return x.ContentEncoding + } + return 0 +} + +// trpc流式init头的请求元信息 +type TrpcStreamInitRequestMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 主调服务的名称 + // trpc协议下的规范格式: trpc.应用名.服务名.pb的service名, 4段 + Caller []byte `protobuf:"bytes,1,opt,name=caller,proto3" json:"caller,omitempty"` + // 被调服务的路由名称 + // trpc协议下的规范格式,trpc.应用名.服务名.pb的service名[.接口名] + // 前4段是必须有,接口可选。 + Callee []byte `protobuf:"bytes,2,opt,name=callee,proto3" json:"callee,omitempty"` + // 调用服务的接口名 + // 规范格式: /package.Service名称/接口名 + Func []byte `protobuf:"bytes,3,opt,name=func,proto3" json:"func,omitempty"` + // 框架信息透传的消息类型 + // 比如调用链、染色key、灰度、鉴权、多环境、set名称等的标识 + // 具体值与TrpcMessageType对应 + MessageType uint32 `protobuf:"varint,4,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"` + // 框架透传的信息key-value对,目前分两部分 + // 1是框架层要透传的信息,key的名字要以trpc-开头 + // 2是业务层要透传的信息,业务可以自行设置 + // 注意: trans_info中的key-value对会全链路透传,业务请谨慎使用! + TransInfo map[string][]byte `protobuf:"bytes,5,rep,name=trans_info,json=transInfo,proto3" json:"trans_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *TrpcStreamInitRequestMeta) Reset() { + *x = TrpcStreamInitRequestMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrpcStreamInitRequestMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrpcStreamInitRequestMeta) ProtoMessage() {} + +func (x *TrpcStreamInitRequestMeta) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrpcStreamInitRequestMeta.ProtoReflect.Descriptor instead. +func (*TrpcStreamInitRequestMeta) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{1} +} + +func (x *TrpcStreamInitRequestMeta) GetCaller() []byte { + if x != nil { + return x.Caller + } + return nil +} + +func (x *TrpcStreamInitRequestMeta) GetCallee() []byte { + if x != nil { + return x.Callee + } + return nil +} + +func (x *TrpcStreamInitRequestMeta) GetFunc() []byte { + if x != nil { + return x.Func + } + return nil +} + +func (x *TrpcStreamInitRequestMeta) GetMessageType() uint32 { + if x != nil { + return x.MessageType + } + return 0 +} + +func (x *TrpcStreamInitRequestMeta) GetTransInfo() map[string][]byte { + if x != nil { + return x.TransInfo + } + return nil +} + +// trpc流式init头的响应元信息 +type TrpcStreamInitResponseMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 请求在框架层的错误返回码 + // 具体值与TrpcRetCode对应 + Ret int32 `protobuf:"varint,1,opt,name=ret,proto3" json:"ret,omitempty"` + // 调用结果信息描述 + // 失败的时候用 + ErrorMsg []byte `protobuf:"bytes,2,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` +} + +func (x *TrpcStreamInitResponseMeta) Reset() { + *x = TrpcStreamInitResponseMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrpcStreamInitResponseMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrpcStreamInitResponseMeta) ProtoMessage() {} + +func (x *TrpcStreamInitResponseMeta) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrpcStreamInitResponseMeta.ProtoReflect.Descriptor instead. +func (*TrpcStreamInitResponseMeta) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{2} +} + +func (x *TrpcStreamInitResponseMeta) GetRet() int32 { + if x != nil { + return x.Ret + } + return 0 +} + +func (x *TrpcStreamInitResponseMeta) GetErrorMsg() []byte { + if x != nil { + return x.ErrorMsg + } + return nil +} + +// trpc流式的流控帧头元信息定义 +type TrpcStreamFeedBackMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 增加的窗口大小 + WindowSizeIncrement uint32 `protobuf:"varint,1,opt,name=window_size_increment,json=windowSizeIncrement,proto3" json:"window_size_increment,omitempty"` +} + +func (x *TrpcStreamFeedBackMeta) Reset() { + *x = TrpcStreamFeedBackMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrpcStreamFeedBackMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrpcStreamFeedBackMeta) ProtoMessage() {} + +func (x *TrpcStreamFeedBackMeta) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrpcStreamFeedBackMeta.ProtoReflect.Descriptor instead. +func (*TrpcStreamFeedBackMeta) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{3} +} + +func (x *TrpcStreamFeedBackMeta) GetWindowSizeIncrement() uint32 { + if x != nil { + return x.WindowSizeIncrement + } + return 0 +} + +// trpc流式的RESET帧头消息定义 +type TrpcStreamCloseMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 关闭的类型,关闭一端,还是全部关闭 + CloseType int32 `protobuf:"varint,1,opt,name=close_type,json=closeType,proto3" json:"close_type,omitempty"` + // close返回码 + // 代表框架层的错误 + Ret int32 `protobuf:"varint,2,opt,name=ret,proto3" json:"ret,omitempty"` + // close信息描述 + Msg []byte `protobuf:"bytes,3,opt,name=msg,proto3" json:"msg,omitempty"` + // 框架信息透传的消息类型 + // 比如调用链、染色key、灰度、鉴权、多环境、set名称等的标识 + // 具体值与TrpcMessageType对应 + MessageType uint32 `protobuf:"varint,4,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"` + // 框架透传的信息key-value对,目前分两部分 + // 1是框架层要透传的信息,key的名字要以trpc-开头 + // 2是业务层要透传的信息,业务可以自行设置 + TransInfo map[string][]byte `protobuf:"bytes,5,rep,name=trans_info,json=transInfo,proto3" json:"trans_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // 接口的错误返回码 + // 建议业务在使用时,标识成功和失败,0代表成功,其它代表失败 + FuncRet int32 `protobuf:"varint,6,opt,name=func_ret,json=funcRet,proto3" json:"func_ret,omitempty"` +} + +func (x *TrpcStreamCloseMeta) Reset() { + *x = TrpcStreamCloseMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TrpcStreamCloseMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TrpcStreamCloseMeta) ProtoMessage() {} + +func (x *TrpcStreamCloseMeta) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TrpcStreamCloseMeta.ProtoReflect.Descriptor instead. +func (*TrpcStreamCloseMeta) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{4} +} + +func (x *TrpcStreamCloseMeta) GetCloseType() int32 { + if x != nil { + return x.CloseType + } + return 0 +} + +func (x *TrpcStreamCloseMeta) GetRet() int32 { + if x != nil { + return x.Ret + } + return 0 +} + +func (x *TrpcStreamCloseMeta) GetMsg() []byte { + if x != nil { + return x.Msg + } + return nil +} + +func (x *TrpcStreamCloseMeta) GetMessageType() uint32 { + if x != nil { + return x.MessageType + } + return 0 +} + +func (x *TrpcStreamCloseMeta) GetTransInfo() map[string][]byte { + if x != nil { + return x.TransInfo + } + return nil +} + +func (x *TrpcStreamCloseMeta) GetFuncRet() int32 { + if x != nil { + return x.FuncRet + } + return 0 +} + +// 请求协议头 +type RequestProtocol struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 协议版本 + // 具体值与TrpcProtoVersion对应 + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // 请求的调用类型 + // 比如: 普通调用,单向调用 + // 具体值与TrpcCallType对应 + CallType uint32 `protobuf:"varint,2,opt,name=call_type,json=callType,proto3" json:"call_type,omitempty"` + // 请求唯一id + RequestId uint32 `protobuf:"varint,3,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // 请求的超时时间,单位ms + Timeout uint32 `protobuf:"varint,4,opt,name=timeout,proto3" json:"timeout,omitempty"` + // 主调服务的名称 + // trpc协议下的规范格式: trpc.应用名.服务名.pb的service名, 4段 + Caller []byte `protobuf:"bytes,5,opt,name=caller,proto3" json:"caller,omitempty"` + // 被调服务的路由名称 + // trpc协议下的规范格式,trpc.应用名.服务名.pb的service名[.接口名] + // 前4段是必须有,接口可选。 + Callee []byte `protobuf:"bytes,6,opt,name=callee,proto3" json:"callee,omitempty"` + // 调用服务的接口名 + // 规范格式: /package.Service名称/接口名 + Func []byte `protobuf:"bytes,7,opt,name=func,proto3" json:"func,omitempty"` + // 框架信息透传的消息类型 + // 比如调用链、染色key、灰度、鉴权、多环境、set名称等的标识 + // 具体值与TrpcMessageType对应 + MessageType uint32 `protobuf:"varint,8,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"` + // 框架透传的信息key-value对,目前分两部分 + // 1是框架层要透传的信息,key的名字要以trpc-开头 + // 2是业务层要透传的信息,业务可以自行设置 + TransInfo map[string][]byte `protobuf:"bytes,9,rep,name=trans_info,json=transInfo,proto3" json:"trans_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // 请求数据的序列化类型 + // 比如: proto/jce/json, 默认proto + // 具体值与TrpcContentEncodeType对应 + ContentType uint32 `protobuf:"varint,10,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // 请求数据使用的压缩方式 + // 比如: gzip/snappy/..., 默认不使用 + // 具体值与TrpcCompressType对应 + ContentEncoding uint32 `protobuf:"varint,11,opt,name=content_encoding,json=contentEncoding,proto3" json:"content_encoding,omitempty"` + // attachment大小 + AttachmentSize uint32 `protobuf:"varint,12,opt,name=attachment_size,json=attachmentSize,proto3" json:"attachment_size,omitempty"` +} + +func (x *RequestProtocol) Reset() { + *x = RequestProtocol{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestProtocol) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestProtocol) ProtoMessage() {} + +func (x *RequestProtocol) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestProtocol.ProtoReflect.Descriptor instead. +func (*RequestProtocol) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{5} +} + +func (x *RequestProtocol) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *RequestProtocol) GetCallType() uint32 { + if x != nil { + return x.CallType + } + return 0 +} + +func (x *RequestProtocol) GetRequestId() uint32 { + if x != nil { + return x.RequestId + } + return 0 +} + +func (x *RequestProtocol) GetTimeout() uint32 { + if x != nil { + return x.Timeout + } + return 0 +} + +func (x *RequestProtocol) GetCaller() []byte { + if x != nil { + return x.Caller + } + return nil +} + +func (x *RequestProtocol) GetCallee() []byte { + if x != nil { + return x.Callee + } + return nil +} + +func (x *RequestProtocol) GetFunc() []byte { + if x != nil { + return x.Func + } + return nil +} + +func (x *RequestProtocol) GetMessageType() uint32 { + if x != nil { + return x.MessageType + } + return 0 +} + +func (x *RequestProtocol) GetTransInfo() map[string][]byte { + if x != nil { + return x.TransInfo + } + return nil +} + +func (x *RequestProtocol) GetContentType() uint32 { + if x != nil { + return x.ContentType + } + return 0 +} + +func (x *RequestProtocol) GetContentEncoding() uint32 { + if x != nil { + return x.ContentEncoding + } + return 0 +} + +func (x *RequestProtocol) GetAttachmentSize() uint32 { + if x != nil { + return x.AttachmentSize + } + return 0 +} + +// 响应协议头 +type ResponseProtocol struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // 协议版本 + // 具体值与TrpcProtoVersion对应 + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // 请求的调用类型 + // 比如: 普通调用,单向调用 + // 具体值与TrpcCallType对应 + CallType uint32 `protobuf:"varint,2,opt,name=call_type,json=callType,proto3" json:"call_type,omitempty"` + // 请求唯一id + RequestId uint32 `protobuf:"varint,3,opt,name=request_id,json=requestId,proto3" json:"request_id,omitempty"` + // 请求在框架层的错误返回码 + // 具体值与TrpcRetCode对应 + Ret int32 `protobuf:"varint,4,opt,name=ret,proto3" json:"ret,omitempty"` + // 接口的错误返回码 + // 建议业务在使用时,标识成功和失败,0代表成功,其它代表失败 + FuncRet int32 `protobuf:"varint,5,opt,name=func_ret,json=funcRet,proto3" json:"func_ret,omitempty"` + // 调用结果信息描述 + // 失败的时候用 + ErrorMsg []byte `protobuf:"bytes,6,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` + // 框架信息透传的消息类型 + // 比如调用链、染色key、灰度、鉴权、多环境、set名称等的标识 + // 具体值与TrpcMessageType对应 + MessageType uint32 `protobuf:"varint,7,opt,name=message_type,json=messageType,proto3" json:"message_type,omitempty"` + // 框架透传回来的信息key-value对, + // 目前分两部分 + // 1是框架层透传回来的信息,key的名字要以trpc-开头 + // 2是业务层透传回来的信息,业务可以自行设置 + TransInfo map[string][]byte `protobuf:"bytes,8,rep,name=trans_info,json=transInfo,proto3" json:"trans_info,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // 响应数据的编码类型 + // 比如: proto/jce/json, 默认proto + // 具体值与TrpcContentEncodeType对应 + ContentType uint32 `protobuf:"varint,9,opt,name=content_type,json=contentType,proto3" json:"content_type,omitempty"` + // 响应数据使用的压缩方式 + // 比如: gzip/snappy/..., 默认不使用 + // 具体值与TrpcCompressType对应 + ContentEncoding uint32 `protobuf:"varint,10,opt,name=content_encoding,json=contentEncoding,proto3" json:"content_encoding,omitempty"` + // attachment大小 + AttachmentSize uint32 `protobuf:"varint,12,opt,name=attachment_size,json=attachmentSize,proto3" json:"attachment_size,omitempty"` +} + +func (x *ResponseProtocol) Reset() { + *x = ResponseProtocol{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_trpc_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResponseProtocol) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResponseProtocol) ProtoMessage() {} + +func (x *ResponseProtocol) ProtoReflect() protoreflect.Message { + mi := &file_trpc_trpc_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ResponseProtocol.ProtoReflect.Descriptor instead. +func (*ResponseProtocol) Descriptor() ([]byte, []int) { + return file_trpc_trpc_proto_rawDescGZIP(), []int{6} +} + +func (x *ResponseProtocol) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *ResponseProtocol) GetCallType() uint32 { + if x != nil { + return x.CallType + } + return 0 +} + +func (x *ResponseProtocol) GetRequestId() uint32 { + if x != nil { + return x.RequestId + } + return 0 +} + +func (x *ResponseProtocol) GetRet() int32 { + if x != nil { + return x.Ret + } + return 0 +} + +func (x *ResponseProtocol) GetFuncRet() int32 { + if x != nil { + return x.FuncRet + } + return 0 +} + +func (x *ResponseProtocol) GetErrorMsg() []byte { + if x != nil { + return x.ErrorMsg + } + return nil +} + +func (x *ResponseProtocol) GetMessageType() uint32 { + if x != nil { + return x.MessageType + } + return 0 +} + +func (x *ResponseProtocol) GetTransInfo() map[string][]byte { + if x != nil { + return x.TransInfo + } + return nil +} + +func (x *ResponseProtocol) GetContentType() uint32 { + if x != nil { + return x.ContentType + } + return 0 +} + +func (x *ResponseProtocol) GetContentEncoding() uint32 { + if x != nil { + return x.ContentEncoding + } + return 0 +} + +func (x *ResponseProtocol) GetAttachmentSize() uint32 { + if x != nil { + return x.AttachmentSize + } + return 0 +} + +var File_trpc_trpc_proto protoreflect.FileDescriptor + +var file_trpc_trpc_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x04, 0x74, 0x72, 0x70, 0x63, 0x22, 0x97, 0x02, 0x0a, 0x12, 0x54, 0x72, 0x70, 0x63, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x69, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x42, + 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x70, 0x63, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x12, 0x45, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x74, 0x72, 0x70, 0x63, + 0x2e, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x0c, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x28, 0x0a, 0x10, 0x69, 0x6e, 0x69, + 0x74, 0x5f, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, + 0x67, 0x22, 0x8f, 0x02, 0x0a, 0x19, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, + 0x75, 0x6e, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d, 0x0a, 0x0a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x5f, + 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x74, 0x72, 0x70, + 0x63, 0x2e, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x6e, 0x69, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x4b, 0x0a, 0x1a, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, + 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, + 0x22, 0x4c, 0x0a, 0x16, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x46, 0x65, + 0x65, 0x64, 0x42, 0x61, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x53, 0x69, 0x7a, 0x65, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x9d, + 0x02, 0x0a, 0x13, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, 0x6f, + 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x47, 0x0a, 0x0a, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x72, 0x65, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x66, 0x75, 0x6e, 0x63, 0x52, 0x65, 0x74, + 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe2, + 0x03, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x21, + 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x27, 0x0a, 0x0f, + 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, + 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0xd0, 0x03, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x10, + 0x0a, 0x03, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x72, 0x65, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x5f, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x07, 0x66, 0x75, 0x6e, 0x63, 0x52, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x44, 0x0a, 0x0a, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x66, + 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, + 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, + 0x27, 0x0a, 0x0f, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x2a, 0x39, 0x0a, 0x09, 0x54, 0x72, 0x70, 0x63, 0x4d, 0x61, + 0x67, 0x69, 0x63, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x44, 0x45, 0x46, 0x41, + 0x55, 0x4c, 0x54, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x10, 0x54, 0x52, + 0x50, 0x43, 0x5f, 0x4d, 0x41, 0x47, 0x49, 0x43, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0xb0, + 0x12, 0x2a, 0x40, 0x0a, 0x11, 0x54, 0x72, 0x70, 0x63, 0x44, 0x61, 0x74, 0x61, 0x46, 0x72, 0x61, + 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x55, + 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x41, 0x4d, + 0x45, 0x10, 0x01, 0x2a, 0x9a, 0x01, 0x0a, 0x13, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x55, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, + 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x10, 0x02, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, + 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x5f, 0x46, 0x45, 0x45, 0x44, 0x42, 0x41, 0x43, + 0x4b, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, + 0x41, 0x4d, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x04, + 0x2a, 0x43, 0x0a, 0x13, 0x54, 0x72, 0x70, 0x63, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6c, + 0x6f, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x00, 0x12, 0x15, + 0x0a, 0x11, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x52, 0x45, + 0x53, 0x45, 0x54, 0x10, 0x01, 0x2a, 0x25, 0x0a, 0x10, 0x54, 0x72, 0x70, 0x63, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x5f, 0x56, 0x31, 0x10, 0x00, 0x2a, 0x39, 0x0a, 0x0c, + 0x54, 0x72, 0x70, 0x63, 0x43, 0x61, 0x6c, 0x6c, 0x54, 0x79, 0x70, 0x65, 0x12, 0x13, 0x0a, 0x0f, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x55, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, + 0x00, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4f, 0x4e, 0x45, 0x57, 0x41, 0x59, + 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x2a, 0xa1, 0x01, 0x0a, 0x0f, 0x54, 0x72, 0x70, 0x63, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x17, 0x0a, + 0x13, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x44, 0x59, 0x45, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x45, 0x53, + 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x54, + 0x52, 0x41, 0x43, 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x02, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x45, 0x4e, 0x56, + 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x04, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, + 0x50, 0x43, 0x5f, 0x47, 0x52, 0x49, 0x44, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, + 0x08, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x54, 0x4e, 0x41, 0x4d, + 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x10, 0x2a, 0xb8, 0x01, 0x0a, 0x15, + 0x54, 0x72, 0x70, 0x63, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x50, 0x52, + 0x4f, 0x54, 0x4f, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4a, 0x43, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x10, + 0x01, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4a, 0x53, 0x4f, 0x4e, 0x5f, 0x45, + 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x46, 0x4c, 0x41, 0x54, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, + 0x45, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4e, 0x4f, 0x4f, 0x50, + 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x58, 0x4d, 0x4c, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x05, 0x12, 0x16, + 0x0a, 0x12, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x54, 0x48, 0x52, 0x49, 0x46, 0x54, 0x5f, 0x45, 0x4e, + 0x43, 0x4f, 0x44, 0x45, 0x10, 0x06, 0x2a, 0xf2, 0x01, 0x0a, 0x10, 0x54, 0x72, 0x70, 0x63, 0x43, + 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, + 0x52, 0x45, 0x53, 0x53, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x47, + 0x5a, 0x49, 0x50, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x18, + 0x0a, 0x14, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x50, 0x59, 0x5f, 0x43, 0x4f, + 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x52, 0x50, 0x43, + 0x5f, 0x5a, 0x4c, 0x49, 0x42, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, 0x03, + 0x12, 0x1f, 0x0a, 0x1b, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x50, 0x59, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, + 0x04, 0x12, 0x1e, 0x0a, 0x1a, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x4e, 0x41, 0x50, 0x50, 0x59, + 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, + 0x05, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4c, 0x5a, 0x34, 0x5f, 0x46, 0x52, + 0x41, 0x4d, 0x45, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, 0x06, 0x12, 0x1b, + 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x4c, 0x5a, 0x34, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x52, 0x45, 0x53, 0x53, 0x10, 0x07, 0x2a, 0xd1, 0x0d, 0x0a, 0x0b, + 0x54, 0x72, 0x70, 0x63, 0x52, 0x65, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x4b, 0x45, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x01, + 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, + 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x53, 0x45, + 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x0b, 0x12, 0x1a, 0x0a, 0x16, 0x54, + 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x46, 0x55, 0x4e, + 0x43, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x0c, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x45, + 0x52, 0x52, 0x10, 0x15, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x45, 0x52, 0x52, + 0x10, 0x16, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x45, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x17, 0x12, + 0x25, 0x0a, 0x21, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x46, + 0x55, 0x4c, 0x4c, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, + 0x5f, 0x45, 0x52, 0x52, 0x10, 0x18, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x10, 0x1f, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x29, 0x12, 0x1c, 0x0a, 0x18, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x33, 0x12, 0x22, 0x0a, 0x1e, 0x54, 0x52, + 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x4f, 0x4b, 0x45, + 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x65, 0x12, 0x25, + 0x0a, 0x21, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x46, 0x55, + 0x4c, 0x4c, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, + 0x45, 0x52, 0x52, 0x10, 0x66, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x5f, 0x45, 0x52, 0x52, + 0x10, 0x6f, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x79, 0x12, 0x1a, + 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, + 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x7a, 0x12, 0x1b, 0x0a, 0x17, 0x54, 0x52, + 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x45, + 0x44, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x7b, 0x12, 0x1c, 0x0a, 0x18, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x4c, 0x4f, 0x41, 0x44, 0x5f, + 0x45, 0x52, 0x52, 0x10, 0x7c, 0x12, 0x1b, 0x0a, 0x16, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x4f, 0x55, 0x54, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x10, + 0x83, 0x01, 0x12, 0x1c, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, + 0x54, 0x5f, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x8d, 0x01, + 0x12, 0x1d, 0x0a, 0x18, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x97, 0x01, 0x12, + 0x1d, 0x0a, 0x18, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x43, + 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xa1, 0x01, 0x12, 0x1f, + 0x0a, 0x1a, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x46, 0x52, 0x41, 0x4d, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xab, 0x01, 0x12, + 0x23, 0x0a, 0x1e, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x45, 0x52, + 0x52, 0x10, 0xc9, 0x01, 0x12, 0x2c, 0x0a, 0x27, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, + 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x45, + 0x58, 0x43, 0x45, 0x45, 0x44, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x10, + 0xd3, 0x01, 0x12, 0x22, 0x0a, 0x1d, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, + 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x5f, + 0x45, 0x52, 0x52, 0x10, 0xdd, 0x01, 0x12, 0x22, 0x0a, 0x1d, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, + 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x45, 0x43, + 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xde, 0x01, 0x12, 0x21, 0x0a, 0x1c, 0x54, 0x52, + 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, + 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0xe7, 0x01, 0x12, 0x2a, 0x0a, + 0x25, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, + 0x4f, 0x57, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xe8, 0x01, 0x12, 0x27, 0x0a, 0x22, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, + 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, + 0xe9, 0x01, 0x12, 0x29, 0x0a, 0x24, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, + 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x54, + 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xea, 0x01, 0x12, 0x20, 0x0a, + 0x1b, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, + 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0xfb, 0x01, 0x12, + 0x26, 0x0a, 0x21, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, + 0x5f, 0x45, 0x52, 0x52, 0x10, 0xfc, 0x01, 0x12, 0x26, 0x0a, 0x21, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x45, 0x4d, 0x50, 0x54, 0x59, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xfd, 0x01, 0x12, + 0x28, 0x0a, 0x23, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x53, + 0x45, 0x52, 0x56, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, + 0x55, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xfe, 0x01, 0x12, 0x23, 0x0a, 0x1e, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xad, 0x02, 0x12, 0x2c, + 0x0a, 0x27, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, + 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x5f, + 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xb7, 0x02, 0x12, 0x22, 0x0a, 0x1d, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x5f, 0x45, 0x4e, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xc1, 0x02, + 0x12, 0x22, 0x0a, 0x1d, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, + 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x45, 0x52, + 0x52, 0x10, 0xc2, 0x02, 0x12, 0x21, 0x0a, 0x1c, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, + 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, + 0x5f, 0x45, 0x4e, 0x44, 0x10, 0xcb, 0x02, 0x12, 0x2a, 0x0a, 0x25, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, + 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x45, 0x52, 0x52, + 0x10, 0xcc, 0x02, 0x12, 0x27, 0x0a, 0x22, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, + 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, + 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xcd, 0x02, 0x12, 0x29, 0x0a, 0x24, + 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, + 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, + 0x5f, 0x45, 0x52, 0x52, 0x10, 0xce, 0x02, 0x12, 0x20, 0x0a, 0x1b, 0x54, 0x52, 0x50, 0x43, 0x5f, + 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, + 0x41, 0x44, 0x5f, 0x45, 0x4e, 0x44, 0x10, 0xdf, 0x02, 0x12, 0x26, 0x0a, 0x21, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xe0, + 0x02, 0x12, 0x26, 0x0a, 0x21, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, + 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x45, 0x4d, 0x50, + 0x54, 0x59, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xe1, 0x02, 0x12, 0x28, 0x0a, 0x23, 0x54, 0x52, 0x50, + 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x5f, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x5f, 0x45, 0x52, 0x52, + 0x10, 0xe2, 0x02, 0x12, 0x1c, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x4f, + 0x4b, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xe7, + 0x07, 0x12, 0x1c, 0x0a, 0x17, 0x54, 0x52, 0x50, 0x43, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, + 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xe8, 0x07, 0x42, + 0x60, 0x0a, 0x26, 0x63, 0x6f, 0x6d, 0x2e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, + 0x72, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x0c, 0x54, 0x52, 0x50, 0x43, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5a, 0x28, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2d, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x72, 0x70, + 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_trpc_trpc_proto_rawDescOnce sync.Once + file_trpc_trpc_proto_rawDescData = file_trpc_trpc_proto_rawDesc +) + +func file_trpc_trpc_proto_rawDescGZIP() []byte { + file_trpc_trpc_proto_rawDescOnce.Do(func() { + file_trpc_trpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_trpc_trpc_proto_rawDescData) + }) + return file_trpc_trpc_proto_rawDescData +} + +var file_trpc_trpc_proto_enumTypes = make([]protoimpl.EnumInfo, 10) +var file_trpc_trpc_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_trpc_trpc_proto_goTypes = []interface{}{ + (TrpcMagic)(0), // 0: trpc.TrpcMagic + (TrpcDataFrameType)(0), // 1: trpc.TrpcDataFrameType + (TrpcStreamFrameType)(0), // 2: trpc.TrpcStreamFrameType + (TrpcStreamCloseType)(0), // 3: trpc.TrpcStreamCloseType + (TrpcProtoVersion)(0), // 4: trpc.TrpcProtoVersion + (TrpcCallType)(0), // 5: trpc.TrpcCallType + (TrpcMessageType)(0), // 6: trpc.TrpcMessageType + (TrpcContentEncodeType)(0), // 7: trpc.TrpcContentEncodeType + (TrpcCompressType)(0), // 8: trpc.TrpcCompressType + (TrpcRetCode)(0), // 9: trpc.TrpcRetCode + (*TrpcStreamInitMeta)(nil), // 10: trpc.TrpcStreamInitMeta + (*TrpcStreamInitRequestMeta)(nil), // 11: trpc.TrpcStreamInitRequestMeta + (*TrpcStreamInitResponseMeta)(nil), // 12: trpc.TrpcStreamInitResponseMeta + (*TrpcStreamFeedBackMeta)(nil), // 13: trpc.TrpcStreamFeedBackMeta + (*TrpcStreamCloseMeta)(nil), // 14: trpc.TrpcStreamCloseMeta + (*RequestProtocol)(nil), // 15: trpc.RequestProtocol + (*ResponseProtocol)(nil), // 16: trpc.ResponseProtocol + nil, // 17: trpc.TrpcStreamInitRequestMeta.TransInfoEntry + nil, // 18: trpc.TrpcStreamCloseMeta.TransInfoEntry + nil, // 19: trpc.RequestProtocol.TransInfoEntry + nil, // 20: trpc.ResponseProtocol.TransInfoEntry +} +var file_trpc_trpc_proto_depIdxs = []int32{ + 11, // 0: trpc.TrpcStreamInitMeta.request_meta:type_name -> trpc.TrpcStreamInitRequestMeta + 12, // 1: trpc.TrpcStreamInitMeta.response_meta:type_name -> trpc.TrpcStreamInitResponseMeta + 17, // 2: trpc.TrpcStreamInitRequestMeta.trans_info:type_name -> trpc.TrpcStreamInitRequestMeta.TransInfoEntry + 18, // 3: trpc.TrpcStreamCloseMeta.trans_info:type_name -> trpc.TrpcStreamCloseMeta.TransInfoEntry + 19, // 4: trpc.RequestProtocol.trans_info:type_name -> trpc.RequestProtocol.TransInfoEntry + 20, // 5: trpc.ResponseProtocol.trans_info:type_name -> trpc.ResponseProtocol.TransInfoEntry + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name +} + +func init() { file_trpc_trpc_proto_init() } +func file_trpc_trpc_proto_init() { + if File_trpc_trpc_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_trpc_trpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrpcStreamInitMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrpcStreamInitRequestMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrpcStreamInitResponseMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrpcStreamFeedBackMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TrpcStreamCloseMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestProtocol); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_trpc_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResponseProtocol); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_trpc_proto_rawDesc, + NumEnums: 10, + NumMessages: 11, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_trpc_trpc_proto_goTypes, + DependencyIndexes: file_trpc_trpc_proto_depIdxs, + EnumInfos: file_trpc_trpc_proto_enumTypes, + MessageInfos: file_trpc_trpc_proto_msgTypes, + }.Build() + File_trpc_trpc_proto = out.File + file_trpc_trpc_proto_rawDesc = nil + file_trpc_trpc_proto_goTypes = nil + file_trpc_trpc_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/pb/go/trpc/validate/validate.pb.go b/install/submodules/trpc-protocol/pb/go/trpc/validate/validate.pb.go new file mode 100644 index 0000000..da63ddc --- /dev/null +++ b/install/submodules/trpc-protocol/pb/go/trpc/validate/validate.pb.go @@ -0,0 +1,4188 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.19.1 +// source: trpc/validate/validate.proto + +package validate + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// WellKnownRegex contain some well-known patterns. +type KnownRegex int32 + +const ( + KnownRegex_UNKNOWN KnownRegex = 0 + // HTTP header name as defined by RFC 7230. + KnownRegex_HTTP_HEADER_NAME KnownRegex = 1 + // HTTP header value as defined by RFC 7230. + KnownRegex_HTTP_HEADER_VALUE KnownRegex = 2 +) + +// Enum value maps for KnownRegex. +var ( + KnownRegex_name = map[int32]string{ + 0: "UNKNOWN", + 1: "HTTP_HEADER_NAME", + 2: "HTTP_HEADER_VALUE", + } + KnownRegex_value = map[string]int32{ + "UNKNOWN": 0, + "HTTP_HEADER_NAME": 1, + "HTTP_HEADER_VALUE": 2, + } +) + +func (x KnownRegex) Enum() *KnownRegex { + p := new(KnownRegex) + *p = x + return p +} + +func (x KnownRegex) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (KnownRegex) Descriptor() protoreflect.EnumDescriptor { + return file_trpc_validate_validate_proto_enumTypes[0].Descriptor() +} + +func (KnownRegex) Type() protoreflect.EnumType { + return &file_trpc_validate_validate_proto_enumTypes[0] +} + +func (x KnownRegex) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *KnownRegex) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = KnownRegex(num) + return nil +} + +// Deprecated: Use KnownRegex.Descriptor instead. +func (KnownRegex) EnumDescriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{0} +} + +// FieldRules encapsulates the rules for each type of field. Depending on the +// field, the correct set should be used to ensure proper validations. +type FieldRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *MessageRules `protobuf:"bytes,17,opt,name=message" json:"message,omitempty"` + // Types that are assignable to Type: + // + // *FieldRules_Float + // *FieldRules_Double + // *FieldRules_Int32 + // *FieldRules_Int64 + // *FieldRules_Uint32 + // *FieldRules_Uint64 + // *FieldRules_Sint32 + // *FieldRules_Sint64 + // *FieldRules_Fixed32 + // *FieldRules_Fixed64 + // *FieldRules_Sfixed32 + // *FieldRules_Sfixed64 + // *FieldRules_Bool + // *FieldRules_String_ + // *FieldRules_Bytes + // *FieldRules_Enum + // *FieldRules_Repeated + // *FieldRules_Map + // *FieldRules_Any + // *FieldRules_Duration + // *FieldRules_Timestamp + Type isFieldRules_Type `protobuf_oneof:"type"` +} + +func (x *FieldRules) Reset() { + *x = FieldRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FieldRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FieldRules) ProtoMessage() {} + +func (x *FieldRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FieldRules.ProtoReflect.Descriptor instead. +func (*FieldRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{0} +} + +func (x *FieldRules) GetMessage() *MessageRules { + if x != nil { + return x.Message + } + return nil +} + +func (m *FieldRules) GetType() isFieldRules_Type { + if m != nil { + return m.Type + } + return nil +} + +func (x *FieldRules) GetFloat() *FloatRules { + if x, ok := x.GetType().(*FieldRules_Float); ok { + return x.Float + } + return nil +} + +func (x *FieldRules) GetDouble() *DoubleRules { + if x, ok := x.GetType().(*FieldRules_Double); ok { + return x.Double + } + return nil +} + +func (x *FieldRules) GetInt32() *Int32Rules { + if x, ok := x.GetType().(*FieldRules_Int32); ok { + return x.Int32 + } + return nil +} + +func (x *FieldRules) GetInt64() *Int64Rules { + if x, ok := x.GetType().(*FieldRules_Int64); ok { + return x.Int64 + } + return nil +} + +func (x *FieldRules) GetUint32() *UInt32Rules { + if x, ok := x.GetType().(*FieldRules_Uint32); ok { + return x.Uint32 + } + return nil +} + +func (x *FieldRules) GetUint64() *UInt64Rules { + if x, ok := x.GetType().(*FieldRules_Uint64); ok { + return x.Uint64 + } + return nil +} + +func (x *FieldRules) GetSint32() *SInt32Rules { + if x, ok := x.GetType().(*FieldRules_Sint32); ok { + return x.Sint32 + } + return nil +} + +func (x *FieldRules) GetSint64() *SInt64Rules { + if x, ok := x.GetType().(*FieldRules_Sint64); ok { + return x.Sint64 + } + return nil +} + +func (x *FieldRules) GetFixed32() *Fixed32Rules { + if x, ok := x.GetType().(*FieldRules_Fixed32); ok { + return x.Fixed32 + } + return nil +} + +func (x *FieldRules) GetFixed64() *Fixed64Rules { + if x, ok := x.GetType().(*FieldRules_Fixed64); ok { + return x.Fixed64 + } + return nil +} + +func (x *FieldRules) GetSfixed32() *SFixed32Rules { + if x, ok := x.GetType().(*FieldRules_Sfixed32); ok { + return x.Sfixed32 + } + return nil +} + +func (x *FieldRules) GetSfixed64() *SFixed64Rules { + if x, ok := x.GetType().(*FieldRules_Sfixed64); ok { + return x.Sfixed64 + } + return nil +} + +func (x *FieldRules) GetBool() *BoolRules { + if x, ok := x.GetType().(*FieldRules_Bool); ok { + return x.Bool + } + return nil +} + +func (x *FieldRules) GetString_() *StringRules { + if x, ok := x.GetType().(*FieldRules_String_); ok { + return x.String_ + } + return nil +} + +func (x *FieldRules) GetBytes() *BytesRules { + if x, ok := x.GetType().(*FieldRules_Bytes); ok { + return x.Bytes + } + return nil +} + +func (x *FieldRules) GetEnum() *EnumRules { + if x, ok := x.GetType().(*FieldRules_Enum); ok { + return x.Enum + } + return nil +} + +func (x *FieldRules) GetRepeated() *RepeatedRules { + if x, ok := x.GetType().(*FieldRules_Repeated); ok { + return x.Repeated + } + return nil +} + +func (x *FieldRules) GetMap() *MapRules { + if x, ok := x.GetType().(*FieldRules_Map); ok { + return x.Map + } + return nil +} + +func (x *FieldRules) GetAny() *AnyRules { + if x, ok := x.GetType().(*FieldRules_Any); ok { + return x.Any + } + return nil +} + +func (x *FieldRules) GetDuration() *DurationRules { + if x, ok := x.GetType().(*FieldRules_Duration); ok { + return x.Duration + } + return nil +} + +func (x *FieldRules) GetTimestamp() *TimestampRules { + if x, ok := x.GetType().(*FieldRules_Timestamp); ok { + return x.Timestamp + } + return nil +} + +type isFieldRules_Type interface { + isFieldRules_Type() +} + +type FieldRules_Float struct { + // Scalar Field Types + Float *FloatRules `protobuf:"bytes,1,opt,name=float,oneof"` +} + +type FieldRules_Double struct { + Double *DoubleRules `protobuf:"bytes,2,opt,name=double,oneof"` +} + +type FieldRules_Int32 struct { + Int32 *Int32Rules `protobuf:"bytes,3,opt,name=int32,oneof"` +} + +type FieldRules_Int64 struct { + Int64 *Int64Rules `protobuf:"bytes,4,opt,name=int64,oneof"` +} + +type FieldRules_Uint32 struct { + Uint32 *UInt32Rules `protobuf:"bytes,5,opt,name=uint32,oneof"` +} + +type FieldRules_Uint64 struct { + Uint64 *UInt64Rules `protobuf:"bytes,6,opt,name=uint64,oneof"` +} + +type FieldRules_Sint32 struct { + Sint32 *SInt32Rules `protobuf:"bytes,7,opt,name=sint32,oneof"` +} + +type FieldRules_Sint64 struct { + Sint64 *SInt64Rules `protobuf:"bytes,8,opt,name=sint64,oneof"` +} + +type FieldRules_Fixed32 struct { + Fixed32 *Fixed32Rules `protobuf:"bytes,9,opt,name=fixed32,oneof"` +} + +type FieldRules_Fixed64 struct { + Fixed64 *Fixed64Rules `protobuf:"bytes,10,opt,name=fixed64,oneof"` +} + +type FieldRules_Sfixed32 struct { + Sfixed32 *SFixed32Rules `protobuf:"bytes,11,opt,name=sfixed32,oneof"` +} + +type FieldRules_Sfixed64 struct { + Sfixed64 *SFixed64Rules `protobuf:"bytes,12,opt,name=sfixed64,oneof"` +} + +type FieldRules_Bool struct { + Bool *BoolRules `protobuf:"bytes,13,opt,name=bool,oneof"` +} + +type FieldRules_String_ struct { + String_ *StringRules `protobuf:"bytes,14,opt,name=string,oneof"` +} + +type FieldRules_Bytes struct { + Bytes *BytesRules `protobuf:"bytes,15,opt,name=bytes,oneof"` +} + +type FieldRules_Enum struct { + // Complex Field Types + Enum *EnumRules `protobuf:"bytes,16,opt,name=enum,oneof"` +} + +type FieldRules_Repeated struct { + Repeated *RepeatedRules `protobuf:"bytes,18,opt,name=repeated,oneof"` +} + +type FieldRules_Map struct { + Map *MapRules `protobuf:"bytes,19,opt,name=map,oneof"` +} + +type FieldRules_Any struct { + // Well-Known Field Types + Any *AnyRules `protobuf:"bytes,20,opt,name=any,oneof"` +} + +type FieldRules_Duration struct { + Duration *DurationRules `protobuf:"bytes,21,opt,name=duration,oneof"` +} + +type FieldRules_Timestamp struct { + Timestamp *TimestampRules `protobuf:"bytes,22,opt,name=timestamp,oneof"` +} + +func (*FieldRules_Float) isFieldRules_Type() {} + +func (*FieldRules_Double) isFieldRules_Type() {} + +func (*FieldRules_Int32) isFieldRules_Type() {} + +func (*FieldRules_Int64) isFieldRules_Type() {} + +func (*FieldRules_Uint32) isFieldRules_Type() {} + +func (*FieldRules_Uint64) isFieldRules_Type() {} + +func (*FieldRules_Sint32) isFieldRules_Type() {} + +func (*FieldRules_Sint64) isFieldRules_Type() {} + +func (*FieldRules_Fixed32) isFieldRules_Type() {} + +func (*FieldRules_Fixed64) isFieldRules_Type() {} + +func (*FieldRules_Sfixed32) isFieldRules_Type() {} + +func (*FieldRules_Sfixed64) isFieldRules_Type() {} + +func (*FieldRules_Bool) isFieldRules_Type() {} + +func (*FieldRules_String_) isFieldRules_Type() {} + +func (*FieldRules_Bytes) isFieldRules_Type() {} + +func (*FieldRules_Enum) isFieldRules_Type() {} + +func (*FieldRules_Repeated) isFieldRules_Type() {} + +func (*FieldRules_Map) isFieldRules_Type() {} + +func (*FieldRules_Any) isFieldRules_Type() {} + +func (*FieldRules_Duration) isFieldRules_Type() {} + +func (*FieldRules_Timestamp) isFieldRules_Type() {} + +// FloatRules describes the constraints applied to `float` values +type FloatRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *float32 `protobuf:"fixed32,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *float32 `protobuf:"fixed32,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *float32 `protobuf:"fixed32,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *float32 `protobuf:"fixed32,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *float32 `protobuf:"fixed32,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []float32 `protobuf:"fixed32,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []float32 `protobuf:"fixed32,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *FloatRules) Reset() { + *x = FloatRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FloatRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FloatRules) ProtoMessage() {} + +func (x *FloatRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FloatRules.ProtoReflect.Descriptor instead. +func (*FloatRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{1} +} + +func (x *FloatRules) GetConst() float32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *FloatRules) GetLt() float32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *FloatRules) GetLte() float32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *FloatRules) GetGt() float32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *FloatRules) GetGte() float32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *FloatRules) GetIn() []float32 { + if x != nil { + return x.In + } + return nil +} + +func (x *FloatRules) GetNotIn() []float32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *FloatRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// DoubleRules describes the constraints applied to `double` values +type DoubleRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *float64 `protobuf:"fixed64,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *float64 `protobuf:"fixed64,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *float64 `protobuf:"fixed64,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *float64 `protobuf:"fixed64,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *float64 `protobuf:"fixed64,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []float64 `protobuf:"fixed64,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []float64 `protobuf:"fixed64,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *DoubleRules) Reset() { + *x = DoubleRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DoubleRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DoubleRules) ProtoMessage() {} + +func (x *DoubleRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DoubleRules.ProtoReflect.Descriptor instead. +func (*DoubleRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{2} +} + +func (x *DoubleRules) GetConst() float64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *DoubleRules) GetLt() float64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *DoubleRules) GetLte() float64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *DoubleRules) GetGt() float64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *DoubleRules) GetGte() float64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *DoubleRules) GetIn() []float64 { + if x != nil { + return x.In + } + return nil +} + +func (x *DoubleRules) GetNotIn() []float64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *DoubleRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// Int32Rules describes the constraints applied to `int32` values +type Int32Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int32 `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int32 `protobuf:"varint,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int32 `protobuf:"varint,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int32 `protobuf:"varint,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int32 `protobuf:"varint,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int32 `protobuf:"varint,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int32 `protobuf:"varint,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *Int32Rules) Reset() { + *x = Int32Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Int32Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Int32Rules) ProtoMessage() {} + +func (x *Int32Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Int32Rules.ProtoReflect.Descriptor instead. +func (*Int32Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{3} +} + +func (x *Int32Rules) GetConst() int32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *Int32Rules) GetLt() int32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *Int32Rules) GetLte() int32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *Int32Rules) GetGt() int32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *Int32Rules) GetGte() int32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *Int32Rules) GetIn() []int32 { + if x != nil { + return x.In + } + return nil +} + +func (x *Int32Rules) GetNotIn() []int32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *Int32Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// Int64Rules describes the constraints applied to `int64` values +type Int64Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int64 `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int64 `protobuf:"varint,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int64 `protobuf:"varint,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int64 `protobuf:"varint,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int64 `protobuf:"varint,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int64 `protobuf:"varint,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int64 `protobuf:"varint,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *Int64Rules) Reset() { + *x = Int64Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Int64Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Int64Rules) ProtoMessage() {} + +func (x *Int64Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Int64Rules.ProtoReflect.Descriptor instead. +func (*Int64Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{4} +} + +func (x *Int64Rules) GetConst() int64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *Int64Rules) GetLt() int64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *Int64Rules) GetLte() int64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *Int64Rules) GetGt() int64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *Int64Rules) GetGte() int64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *Int64Rules) GetIn() []int64 { + if x != nil { + return x.In + } + return nil +} + +func (x *Int64Rules) GetNotIn() []int64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *Int64Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// UInt32Rules describes the constraints applied to `uint32` values +type UInt32Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *uint32 `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *uint32 `protobuf:"varint,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *uint32 `protobuf:"varint,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *uint32 `protobuf:"varint,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *uint32 `protobuf:"varint,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []uint32 `protobuf:"varint,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []uint32 `protobuf:"varint,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *UInt32Rules) Reset() { + *x = UInt32Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UInt32Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UInt32Rules) ProtoMessage() {} + +func (x *UInt32Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UInt32Rules.ProtoReflect.Descriptor instead. +func (*UInt32Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{5} +} + +func (x *UInt32Rules) GetConst() uint32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *UInt32Rules) GetLt() uint32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *UInt32Rules) GetLte() uint32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *UInt32Rules) GetGt() uint32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *UInt32Rules) GetGte() uint32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *UInt32Rules) GetIn() []uint32 { + if x != nil { + return x.In + } + return nil +} + +func (x *UInt32Rules) GetNotIn() []uint32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *UInt32Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// UInt64Rules describes the constraints applied to `uint64` values +type UInt64Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *uint64 `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *uint64 `protobuf:"varint,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *uint64 `protobuf:"varint,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *uint64 `protobuf:"varint,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *uint64 `protobuf:"varint,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []uint64 `protobuf:"varint,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []uint64 `protobuf:"varint,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *UInt64Rules) Reset() { + *x = UInt64Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UInt64Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UInt64Rules) ProtoMessage() {} + +func (x *UInt64Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UInt64Rules.ProtoReflect.Descriptor instead. +func (*UInt64Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{6} +} + +func (x *UInt64Rules) GetConst() uint64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *UInt64Rules) GetLt() uint64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *UInt64Rules) GetLte() uint64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *UInt64Rules) GetGt() uint64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *UInt64Rules) GetGte() uint64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *UInt64Rules) GetIn() []uint64 { + if x != nil { + return x.In + } + return nil +} + +func (x *UInt64Rules) GetNotIn() []uint64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *UInt64Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// SInt32Rules describes the constraints applied to `sint32` values +type SInt32Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int32 `protobuf:"zigzag32,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int32 `protobuf:"zigzag32,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int32 `protobuf:"zigzag32,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int32 `protobuf:"zigzag32,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int32 `protobuf:"zigzag32,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int32 `protobuf:"zigzag32,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int32 `protobuf:"zigzag32,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *SInt32Rules) Reset() { + *x = SInt32Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SInt32Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SInt32Rules) ProtoMessage() {} + +func (x *SInt32Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SInt32Rules.ProtoReflect.Descriptor instead. +func (*SInt32Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{7} +} + +func (x *SInt32Rules) GetConst() int32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *SInt32Rules) GetLt() int32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *SInt32Rules) GetLte() int32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *SInt32Rules) GetGt() int32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *SInt32Rules) GetGte() int32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *SInt32Rules) GetIn() []int32 { + if x != nil { + return x.In + } + return nil +} + +func (x *SInt32Rules) GetNotIn() []int32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *SInt32Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// SInt64Rules describes the constraints applied to `sint64` values +type SInt64Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int64 `protobuf:"zigzag64,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int64 `protobuf:"zigzag64,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int64 `protobuf:"zigzag64,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int64 `protobuf:"zigzag64,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int64 `protobuf:"zigzag64,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int64 `protobuf:"zigzag64,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int64 `protobuf:"zigzag64,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *SInt64Rules) Reset() { + *x = SInt64Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SInt64Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SInt64Rules) ProtoMessage() {} + +func (x *SInt64Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SInt64Rules.ProtoReflect.Descriptor instead. +func (*SInt64Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{8} +} + +func (x *SInt64Rules) GetConst() int64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *SInt64Rules) GetLt() int64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *SInt64Rules) GetLte() int64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *SInt64Rules) GetGt() int64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *SInt64Rules) GetGte() int64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *SInt64Rules) GetIn() []int64 { + if x != nil { + return x.In + } + return nil +} + +func (x *SInt64Rules) GetNotIn() []int64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *SInt64Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// Fixed32Rules describes the constraints applied to `fixed32` values +type Fixed32Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *uint32 `protobuf:"fixed32,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *uint32 `protobuf:"fixed32,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *uint32 `protobuf:"fixed32,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *uint32 `protobuf:"fixed32,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *uint32 `protobuf:"fixed32,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []uint32 `protobuf:"fixed32,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []uint32 `protobuf:"fixed32,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *Fixed32Rules) Reset() { + *x = Fixed32Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Fixed32Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Fixed32Rules) ProtoMessage() {} + +func (x *Fixed32Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Fixed32Rules.ProtoReflect.Descriptor instead. +func (*Fixed32Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{9} +} + +func (x *Fixed32Rules) GetConst() uint32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *Fixed32Rules) GetLt() uint32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *Fixed32Rules) GetLte() uint32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *Fixed32Rules) GetGt() uint32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *Fixed32Rules) GetGte() uint32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *Fixed32Rules) GetIn() []uint32 { + if x != nil { + return x.In + } + return nil +} + +func (x *Fixed32Rules) GetNotIn() []uint32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *Fixed32Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// Fixed64Rules describes the constraints applied to `fixed64` values +type Fixed64Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *uint64 `protobuf:"fixed64,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *uint64 `protobuf:"fixed64,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *uint64 `protobuf:"fixed64,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *uint64 `protobuf:"fixed64,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *uint64 `protobuf:"fixed64,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []uint64 `protobuf:"fixed64,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []uint64 `protobuf:"fixed64,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *Fixed64Rules) Reset() { + *x = Fixed64Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Fixed64Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Fixed64Rules) ProtoMessage() {} + +func (x *Fixed64Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Fixed64Rules.ProtoReflect.Descriptor instead. +func (*Fixed64Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{10} +} + +func (x *Fixed64Rules) GetConst() uint64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *Fixed64Rules) GetLt() uint64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *Fixed64Rules) GetLte() uint64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *Fixed64Rules) GetGt() uint64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *Fixed64Rules) GetGte() uint64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *Fixed64Rules) GetIn() []uint64 { + if x != nil { + return x.In + } + return nil +} + +func (x *Fixed64Rules) GetNotIn() []uint64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *Fixed64Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// SFixed32Rules describes the constraints applied to `sfixed32` values +type SFixed32Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int32 `protobuf:"fixed32,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int32 `protobuf:"fixed32,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int32 `protobuf:"fixed32,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int32 `protobuf:"fixed32,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int32 `protobuf:"fixed32,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int32 `protobuf:"fixed32,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int32 `protobuf:"fixed32,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *SFixed32Rules) Reset() { + *x = SFixed32Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SFixed32Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SFixed32Rules) ProtoMessage() {} + +func (x *SFixed32Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SFixed32Rules.ProtoReflect.Descriptor instead. +func (*SFixed32Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{11} +} + +func (x *SFixed32Rules) GetConst() int32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *SFixed32Rules) GetLt() int32 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *SFixed32Rules) GetLte() int32 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *SFixed32Rules) GetGt() int32 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *SFixed32Rules) GetGte() int32 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *SFixed32Rules) GetIn() []int32 { + if x != nil { + return x.In + } + return nil +} + +func (x *SFixed32Rules) GetNotIn() []int32 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *SFixed32Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// SFixed64Rules describes the constraints applied to `sfixed64` values +type SFixed64Rules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int64 `protobuf:"fixed64,1,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *int64 `protobuf:"fixed64,2,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + Lte *int64 `protobuf:"fixed64,3,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + Gt *int64 `protobuf:"fixed64,4,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + Gte *int64 `protobuf:"fixed64,5,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int64 `protobuf:"fixed64,6,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int64 `protobuf:"fixed64,7,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,8,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *SFixed64Rules) Reset() { + *x = SFixed64Rules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SFixed64Rules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SFixed64Rules) ProtoMessage() {} + +func (x *SFixed64Rules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SFixed64Rules.ProtoReflect.Descriptor instead. +func (*SFixed64Rules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{12} +} + +func (x *SFixed64Rules) GetConst() int64 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *SFixed64Rules) GetLt() int64 { + if x != nil && x.Lt != nil { + return *x.Lt + } + return 0 +} + +func (x *SFixed64Rules) GetLte() int64 { + if x != nil && x.Lte != nil { + return *x.Lte + } + return 0 +} + +func (x *SFixed64Rules) GetGt() int64 { + if x != nil && x.Gt != nil { + return *x.Gt + } + return 0 +} + +func (x *SFixed64Rules) GetGte() int64 { + if x != nil && x.Gte != nil { + return *x.Gte + } + return 0 +} + +func (x *SFixed64Rules) GetIn() []int64 { + if x != nil { + return x.In + } + return nil +} + +func (x *SFixed64Rules) GetNotIn() []int64 { + if x != nil { + return x.NotIn + } + return nil +} + +func (x *SFixed64Rules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// BoolRules describes the constraints applied to `bool` values +type BoolRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *bool `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` +} + +func (x *BoolRules) Reset() { + *x = BoolRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BoolRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BoolRules) ProtoMessage() {} + +func (x *BoolRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BoolRules.ProtoReflect.Descriptor instead. +func (*BoolRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{13} +} + +func (x *BoolRules) GetConst() bool { + if x != nil && x.Const != nil { + return *x.Const + } + return false +} + +// StringRules describe the constraints applied to `string` values +type StringRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *string `protobuf:"bytes,1,opt,name=const" json:"const,omitempty"` + // Len specifies that this field must be the specified number of + // characters (Unicode code points). Note that the number of + // characters may differ from the number of bytes in the string. + Len *uint64 `protobuf:"varint,19,opt,name=len" json:"len,omitempty"` + // MinLen specifies that this field must be the specified number of + // characters (Unicode code points) at a minimum. Note that the number of + // characters may differ from the number of bytes in the string. + MinLen *uint64 `protobuf:"varint,2,opt,name=min_len,json=minLen" json:"min_len,omitempty"` + // MaxLen specifies that this field must be the specified number of + // characters (Unicode code points) at a maximum. Note that the number of + // characters may differ from the number of bytes in the string. + MaxLen *uint64 `protobuf:"varint,3,opt,name=max_len,json=maxLen" json:"max_len,omitempty"` + // LenBytes specifies that this field must be the specified number of bytes + // at a minimum + LenBytes *uint64 `protobuf:"varint,20,opt,name=len_bytes,json=lenBytes" json:"len_bytes,omitempty"` + // MinBytes specifies that this field must be the specified number of bytes + // at a minimum + MinBytes *uint64 `protobuf:"varint,4,opt,name=min_bytes,json=minBytes" json:"min_bytes,omitempty"` + // MaxBytes specifies that this field must be the specified number of bytes + // at a maximum + MaxBytes *uint64 `protobuf:"varint,5,opt,name=max_bytes,json=maxBytes" json:"max_bytes,omitempty"` + // Pattern specifes that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + Pattern *string `protobuf:"bytes,6,opt,name=pattern" json:"pattern,omitempty"` + // Prefix specifies that this field must have the specified substring at + // the beginning of the string. + Prefix *string `protobuf:"bytes,7,opt,name=prefix" json:"prefix,omitempty"` + // Suffix specifies that this field must have the specified substring at + // the end of the string. + Suffix *string `protobuf:"bytes,8,opt,name=suffix" json:"suffix,omitempty"` + // Contains specifies that this field must have the specified substring + // anywhere in the string. + Contains *string `protobuf:"bytes,9,opt,name=contains" json:"contains,omitempty"` + // NotContains specifies that this field cannot have the specified substring + // anywhere in the string. + NotContains *string `protobuf:"bytes,23,opt,name=not_contains,json=notContains" json:"not_contains,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []string `protobuf:"bytes,10,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []string `protobuf:"bytes,11,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // WellKnown rules provide advanced constraints against common string + // patterns + // + // Types that are assignable to WellKnown: + // + // *StringRules_Email + // *StringRules_Hostname + // *StringRules_Ip + // *StringRules_Ipv4 + // *StringRules_Ipv6 + // *StringRules_Uri + // *StringRules_UriRef + // *StringRules_Address + // *StringRules_Uuid + // *StringRules_WellKnownRegex + // *StringRules_Alphabets + // *StringRules_Alphanums + // *StringRules_Lowercase + // *StringRules_Tsecstr + WellKnown isStringRules_WellKnown `protobuf_oneof:"well_known"` + // This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable + // strict header validation. + // By default, this is true, and HTTP header validations are RFC-compliant. + // Setting to false will enable a looser validations that only disallows + // \r\n\0 characters, which can be used to bypass header matching rules. + Strict *bool `protobuf:"varint,25,opt,name=strict,def=1" json:"strict,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,26,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +// Default values for StringRules fields. +const ( + Default_StringRules_Strict = bool(true) +) + +func (x *StringRules) Reset() { + *x = StringRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StringRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StringRules) ProtoMessage() {} + +func (x *StringRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StringRules.ProtoReflect.Descriptor instead. +func (*StringRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{14} +} + +func (x *StringRules) GetConst() string { + if x != nil && x.Const != nil { + return *x.Const + } + return "" +} + +func (x *StringRules) GetLen() uint64 { + if x != nil && x.Len != nil { + return *x.Len + } + return 0 +} + +func (x *StringRules) GetMinLen() uint64 { + if x != nil && x.MinLen != nil { + return *x.MinLen + } + return 0 +} + +func (x *StringRules) GetMaxLen() uint64 { + if x != nil && x.MaxLen != nil { + return *x.MaxLen + } + return 0 +} + +func (x *StringRules) GetLenBytes() uint64 { + if x != nil && x.LenBytes != nil { + return *x.LenBytes + } + return 0 +} + +func (x *StringRules) GetMinBytes() uint64 { + if x != nil && x.MinBytes != nil { + return *x.MinBytes + } + return 0 +} + +func (x *StringRules) GetMaxBytes() uint64 { + if x != nil && x.MaxBytes != nil { + return *x.MaxBytes + } + return 0 +} + +func (x *StringRules) GetPattern() string { + if x != nil && x.Pattern != nil { + return *x.Pattern + } + return "" +} + +func (x *StringRules) GetPrefix() string { + if x != nil && x.Prefix != nil { + return *x.Prefix + } + return "" +} + +func (x *StringRules) GetSuffix() string { + if x != nil && x.Suffix != nil { + return *x.Suffix + } + return "" +} + +func (x *StringRules) GetContains() string { + if x != nil && x.Contains != nil { + return *x.Contains + } + return "" +} + +func (x *StringRules) GetNotContains() string { + if x != nil && x.NotContains != nil { + return *x.NotContains + } + return "" +} + +func (x *StringRules) GetIn() []string { + if x != nil { + return x.In + } + return nil +} + +func (x *StringRules) GetNotIn() []string { + if x != nil { + return x.NotIn + } + return nil +} + +func (m *StringRules) GetWellKnown() isStringRules_WellKnown { + if m != nil { + return m.WellKnown + } + return nil +} + +func (x *StringRules) GetEmail() bool { + if x, ok := x.GetWellKnown().(*StringRules_Email); ok { + return x.Email + } + return false +} + +func (x *StringRules) GetHostname() bool { + if x, ok := x.GetWellKnown().(*StringRules_Hostname); ok { + return x.Hostname + } + return false +} + +func (x *StringRules) GetIp() bool { + if x, ok := x.GetWellKnown().(*StringRules_Ip); ok { + return x.Ip + } + return false +} + +func (x *StringRules) GetIpv4() bool { + if x, ok := x.GetWellKnown().(*StringRules_Ipv4); ok { + return x.Ipv4 + } + return false +} + +func (x *StringRules) GetIpv6() bool { + if x, ok := x.GetWellKnown().(*StringRules_Ipv6); ok { + return x.Ipv6 + } + return false +} + +func (x *StringRules) GetUri() bool { + if x, ok := x.GetWellKnown().(*StringRules_Uri); ok { + return x.Uri + } + return false +} + +func (x *StringRules) GetUriRef() bool { + if x, ok := x.GetWellKnown().(*StringRules_UriRef); ok { + return x.UriRef + } + return false +} + +func (x *StringRules) GetAddress() bool { + if x, ok := x.GetWellKnown().(*StringRules_Address); ok { + return x.Address + } + return false +} + +func (x *StringRules) GetUuid() bool { + if x, ok := x.GetWellKnown().(*StringRules_Uuid); ok { + return x.Uuid + } + return false +} + +func (x *StringRules) GetWellKnownRegex() KnownRegex { + if x, ok := x.GetWellKnown().(*StringRules_WellKnownRegex); ok { + return x.WellKnownRegex + } + return KnownRegex_UNKNOWN +} + +func (x *StringRules) GetAlphabets() bool { + if x, ok := x.GetWellKnown().(*StringRules_Alphabets); ok { + return x.Alphabets + } + return false +} + +func (x *StringRules) GetAlphanums() bool { + if x, ok := x.GetWellKnown().(*StringRules_Alphanums); ok { + return x.Alphanums + } + return false +} + +func (x *StringRules) GetLowercase() bool { + if x, ok := x.GetWellKnown().(*StringRules_Lowercase); ok { + return x.Lowercase + } + return false +} + +func (x *StringRules) GetTsecstr() bool { + if x, ok := x.GetWellKnown().(*StringRules_Tsecstr); ok { + return x.Tsecstr + } + return false +} + +func (x *StringRules) GetStrict() bool { + if x != nil && x.Strict != nil { + return *x.Strict + } + return Default_StringRules_Strict +} + +func (x *StringRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +type isStringRules_WellKnown interface { + isStringRules_WellKnown() +} + +type StringRules_Email struct { + // Email specifies that the field must be a valid email address as + // defined by RFC 5322 + Email bool `protobuf:"varint,12,opt,name=email,oneof"` +} + +type StringRules_Hostname struct { + // Hostname specifies that the field must be a valid hostname as + // defined by RFC 1034. This constraint does not support + // internationalized domain names (IDNs). + Hostname bool `protobuf:"varint,13,opt,name=hostname,oneof"` +} + +type StringRules_Ip struct { + // Ip specifies that the field must be a valid IP (v4 or v6) address. + // Valid IPv6 addresses should not include surrounding square brackets. + Ip bool `protobuf:"varint,14,opt,name=ip,oneof"` +} + +type StringRules_Ipv4 struct { + // Ipv4 specifies that the field must be a valid IPv4 address. + Ipv4 bool `protobuf:"varint,15,opt,name=ipv4,oneof"` +} + +type StringRules_Ipv6 struct { + // Ipv6 specifies that the field must be a valid IPv6 address. Valid + // IPv6 addresses should not include surrounding square brackets. + Ipv6 bool `protobuf:"varint,16,opt,name=ipv6,oneof"` +} + +type StringRules_Uri struct { + // Uri specifies that the field must be a valid, absolute URI as defined + // by RFC 3986 + Uri bool `protobuf:"varint,17,opt,name=uri,oneof"` +} + +type StringRules_UriRef struct { + // UriRef specifies that the field must be a valid URI as defined by RFC + // 3986 and may be relative or absolute. + UriRef bool `protobuf:"varint,18,opt,name=uri_ref,json=uriRef,oneof"` +} + +type StringRules_Address struct { + // Address specifies that the field must be either a valid hostname as + // defined by RFC 1034 (which does not support internationalized domain + // names or IDNs), or it can be a valid IP (v4 or v6). + Address bool `protobuf:"varint,21,opt,name=address,oneof"` +} + +type StringRules_Uuid struct { + // Uuid specifies that the field must be a valid UUID as defined by + // RFC 4122 + Uuid bool `protobuf:"varint,22,opt,name=uuid,oneof"` +} + +type StringRules_WellKnownRegex struct { + // WellKnownRegex specifies a common well known pattern defined as a regex. + WellKnownRegex KnownRegex `protobuf:"varint,24,opt,name=well_known_regex,json=wellKnownRegex,enum=trpc.validate.KnownRegex,oneof"` +} + +type StringRules_Alphabets struct { + // Alphabets specifies that the field can only contain alphabets. e.g. aA + Alphabets bool `protobuf:"varint,27,opt,name=alphabets,oneof"` +} + +type StringRules_Alphanums struct { + // Alphanums specifies that the field should contain both alphabet(s) and number(s). e.g. aA1 + Alphanums bool `protobuf:"varint,28,opt,name=alphanums,oneof"` +} + +type StringRules_Lowercase struct { + // Lowercase specifies that the field can only contain lowercase alphabet(s). e.g. aa + Lowercase bool `protobuf:"varint,29,opt,name=lowercase,oneof"` +} + +type StringRules_Tsecstr struct { + // tsecstr specifies that the field can only contain secured strings + Tsecstr bool `protobuf:"varint,30,opt,name=tsecstr,oneof"` +} + +func (*StringRules_Email) isStringRules_WellKnown() {} + +func (*StringRules_Hostname) isStringRules_WellKnown() {} + +func (*StringRules_Ip) isStringRules_WellKnown() {} + +func (*StringRules_Ipv4) isStringRules_WellKnown() {} + +func (*StringRules_Ipv6) isStringRules_WellKnown() {} + +func (*StringRules_Uri) isStringRules_WellKnown() {} + +func (*StringRules_UriRef) isStringRules_WellKnown() {} + +func (*StringRules_Address) isStringRules_WellKnown() {} + +func (*StringRules_Uuid) isStringRules_WellKnown() {} + +func (*StringRules_WellKnownRegex) isStringRules_WellKnown() {} + +func (*StringRules_Alphabets) isStringRules_WellKnown() {} + +func (*StringRules_Alphanums) isStringRules_WellKnown() {} + +func (*StringRules_Lowercase) isStringRules_WellKnown() {} + +func (*StringRules_Tsecstr) isStringRules_WellKnown() {} + +// BytesRules describe the constraints applied to `bytes` values +type BytesRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const []byte `protobuf:"bytes,1,opt,name=const" json:"const,omitempty"` + // Len specifies that this field must be the specified number of bytes + Len *uint64 `protobuf:"varint,13,opt,name=len" json:"len,omitempty"` + // MinLen specifies that this field must be the specified number of bytes + // at a minimum + MinLen *uint64 `protobuf:"varint,2,opt,name=min_len,json=minLen" json:"min_len,omitempty"` + // MaxLen specifies that this field must be the specified number of bytes + // at a maximum + MaxLen *uint64 `protobuf:"varint,3,opt,name=max_len,json=maxLen" json:"max_len,omitempty"` + // Pattern specifes that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + Pattern *string `protobuf:"bytes,4,opt,name=pattern" json:"pattern,omitempty"` + // Prefix specifies that this field must have the specified bytes at the + // beginning of the string. + Prefix []byte `protobuf:"bytes,5,opt,name=prefix" json:"prefix,omitempty"` + // Suffix specifies that this field must have the specified bytes at the + // end of the string. + Suffix []byte `protobuf:"bytes,6,opt,name=suffix" json:"suffix,omitempty"` + // Contains specifies that this field must have the specified bytes + // anywhere in the string. + Contains []byte `protobuf:"bytes,7,opt,name=contains" json:"contains,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In [][]byte `protobuf:"bytes,8,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn [][]byte `protobuf:"bytes,9,rep,name=not_in,json=notIn" json:"not_in,omitempty"` + // WellKnown rules provide advanced constraints against common byte + // patterns + // + // Types that are assignable to WellKnown: + // + // *BytesRules_Ip + // *BytesRules_Ipv4 + // *BytesRules_Ipv6 + WellKnown isBytesRules_WellKnown `protobuf_oneof:"well_known"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,14,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *BytesRules) Reset() { + *x = BytesRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BytesRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BytesRules) ProtoMessage() {} + +func (x *BytesRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BytesRules.ProtoReflect.Descriptor instead. +func (*BytesRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{15} +} + +func (x *BytesRules) GetConst() []byte { + if x != nil { + return x.Const + } + return nil +} + +func (x *BytesRules) GetLen() uint64 { + if x != nil && x.Len != nil { + return *x.Len + } + return 0 +} + +func (x *BytesRules) GetMinLen() uint64 { + if x != nil && x.MinLen != nil { + return *x.MinLen + } + return 0 +} + +func (x *BytesRules) GetMaxLen() uint64 { + if x != nil && x.MaxLen != nil { + return *x.MaxLen + } + return 0 +} + +func (x *BytesRules) GetPattern() string { + if x != nil && x.Pattern != nil { + return *x.Pattern + } + return "" +} + +func (x *BytesRules) GetPrefix() []byte { + if x != nil { + return x.Prefix + } + return nil +} + +func (x *BytesRules) GetSuffix() []byte { + if x != nil { + return x.Suffix + } + return nil +} + +func (x *BytesRules) GetContains() []byte { + if x != nil { + return x.Contains + } + return nil +} + +func (x *BytesRules) GetIn() [][]byte { + if x != nil { + return x.In + } + return nil +} + +func (x *BytesRules) GetNotIn() [][]byte { + if x != nil { + return x.NotIn + } + return nil +} + +func (m *BytesRules) GetWellKnown() isBytesRules_WellKnown { + if m != nil { + return m.WellKnown + } + return nil +} + +func (x *BytesRules) GetIp() bool { + if x, ok := x.GetWellKnown().(*BytesRules_Ip); ok { + return x.Ip + } + return false +} + +func (x *BytesRules) GetIpv4() bool { + if x, ok := x.GetWellKnown().(*BytesRules_Ipv4); ok { + return x.Ipv4 + } + return false +} + +func (x *BytesRules) GetIpv6() bool { + if x, ok := x.GetWellKnown().(*BytesRules_Ipv6); ok { + return x.Ipv6 + } + return false +} + +func (x *BytesRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +type isBytesRules_WellKnown interface { + isBytesRules_WellKnown() +} + +type BytesRules_Ip struct { + // Ip specifies that the field must be a valid IP (v4 or v6) address in + // byte format + Ip bool `protobuf:"varint,10,opt,name=ip,oneof"` +} + +type BytesRules_Ipv4 struct { + // Ipv4 specifies that the field must be a valid IPv4 address in byte + // format + Ipv4 bool `protobuf:"varint,11,opt,name=ipv4,oneof"` +} + +type BytesRules_Ipv6 struct { + // Ipv6 specifies that the field must be a valid IPv6 address in byte + // format + Ipv6 bool `protobuf:"varint,12,opt,name=ipv6,oneof"` +} + +func (*BytesRules_Ip) isBytesRules_WellKnown() {} + +func (*BytesRules_Ipv4) isBytesRules_WellKnown() {} + +func (*BytesRules_Ipv6) isBytesRules_WellKnown() {} + +// EnumRules describe the constraints applied to enum values +type EnumRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Const specifies that this field must be exactly the specified value + Const *int32 `protobuf:"varint,1,opt,name=const" json:"const,omitempty"` + // DefinedOnly specifies that this field must be only one of the defined + // values for this enum, failing on any undefined value. + DefinedOnly *bool `protobuf:"varint,2,opt,name=defined_only,json=definedOnly" json:"defined_only,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []int32 `protobuf:"varint,3,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []int32 `protobuf:"varint,4,rep,name=not_in,json=notIn" json:"not_in,omitempty"` +} + +func (x *EnumRules) Reset() { + *x = EnumRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EnumRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EnumRules) ProtoMessage() {} + +func (x *EnumRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EnumRules.ProtoReflect.Descriptor instead. +func (*EnumRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{16} +} + +func (x *EnumRules) GetConst() int32 { + if x != nil && x.Const != nil { + return *x.Const + } + return 0 +} + +func (x *EnumRules) GetDefinedOnly() bool { + if x != nil && x.DefinedOnly != nil { + return *x.DefinedOnly + } + return false +} + +func (x *EnumRules) GetIn() []int32 { + if x != nil { + return x.In + } + return nil +} + +func (x *EnumRules) GetNotIn() []int32 { + if x != nil { + return x.NotIn + } + return nil +} + +// MessageRules describe the constraints applied to embedded message values. +// For message-type fields, validation is performed recursively. +type MessageRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Skip specifies that the validation rules of this field should not be + // evaluated + Skip *bool `protobuf:"varint,1,opt,name=skip" json:"skip,omitempty"` + // Required specifies that this field must be set + Required *bool `protobuf:"varint,2,opt,name=required" json:"required,omitempty"` +} + +func (x *MessageRules) Reset() { + *x = MessageRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageRules) ProtoMessage() {} + +func (x *MessageRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageRules.ProtoReflect.Descriptor instead. +func (*MessageRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{17} +} + +func (x *MessageRules) GetSkip() bool { + if x != nil && x.Skip != nil { + return *x.Skip + } + return false +} + +func (x *MessageRules) GetRequired() bool { + if x != nil && x.Required != nil { + return *x.Required + } + return false +} + +// RepeatedRules describe the constraints applied to `repeated` values +type RepeatedRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // MinItems specifies that this field must have the specified number of + // items at a minimum + MinItems *uint64 `protobuf:"varint,1,opt,name=min_items,json=minItems" json:"min_items,omitempty"` + // MaxItems specifies that this field must have the specified number of + // items at a maximum + MaxItems *uint64 `protobuf:"varint,2,opt,name=max_items,json=maxItems" json:"max_items,omitempty"` + // Unique specifies that all elements in this field must be unique. This + // contraint is only applicable to scalar and enum types (messages are not + // supported). + Unique *bool `protobuf:"varint,3,opt,name=unique" json:"unique,omitempty"` + // Items specifies the contraints to be applied to each item in the field. + // Repeated message fields will still execute validation against each item + // unless skip is specified here. + Items *FieldRules `protobuf:"bytes,4,opt,name=items" json:"items,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,5,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *RepeatedRules) Reset() { + *x = RepeatedRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepeatedRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepeatedRules) ProtoMessage() {} + +func (x *RepeatedRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RepeatedRules.ProtoReflect.Descriptor instead. +func (*RepeatedRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{18} +} + +func (x *RepeatedRules) GetMinItems() uint64 { + if x != nil && x.MinItems != nil { + return *x.MinItems + } + return 0 +} + +func (x *RepeatedRules) GetMaxItems() uint64 { + if x != nil && x.MaxItems != nil { + return *x.MaxItems + } + return 0 +} + +func (x *RepeatedRules) GetUnique() bool { + if x != nil && x.Unique != nil { + return *x.Unique + } + return false +} + +func (x *RepeatedRules) GetItems() *FieldRules { + if x != nil { + return x.Items + } + return nil +} + +func (x *RepeatedRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// MapRules describe the constraints applied to `map` values +type MapRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // MinPairs specifies that this field must have the specified number of + // KVs at a minimum + MinPairs *uint64 `protobuf:"varint,1,opt,name=min_pairs,json=minPairs" json:"min_pairs,omitempty"` + // MaxPairs specifies that this field must have the specified number of + // KVs at a maximum + MaxPairs *uint64 `protobuf:"varint,2,opt,name=max_pairs,json=maxPairs" json:"max_pairs,omitempty"` + // NoSparse specifies values in this field cannot be unset. This only + // applies to map's with message value types. + NoSparse *bool `protobuf:"varint,3,opt,name=no_sparse,json=noSparse" json:"no_sparse,omitempty"` + // Keys specifies the constraints to be applied to each key in the field. + Keys *FieldRules `protobuf:"bytes,4,opt,name=keys" json:"keys,omitempty"` + // Values specifies the constraints to be applied to the value of each key + // in the field. Message values will still have their validations evaluated + // unless skip is specified here. + Values *FieldRules `protobuf:"bytes,5,opt,name=values" json:"values,omitempty"` + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + IgnoreEmpty *bool `protobuf:"varint,6,opt,name=ignore_empty,json=ignoreEmpty" json:"ignore_empty,omitempty"` +} + +func (x *MapRules) Reset() { + *x = MapRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MapRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MapRules) ProtoMessage() {} + +func (x *MapRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MapRules.ProtoReflect.Descriptor instead. +func (*MapRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{19} +} + +func (x *MapRules) GetMinPairs() uint64 { + if x != nil && x.MinPairs != nil { + return *x.MinPairs + } + return 0 +} + +func (x *MapRules) GetMaxPairs() uint64 { + if x != nil && x.MaxPairs != nil { + return *x.MaxPairs + } + return 0 +} + +func (x *MapRules) GetNoSparse() bool { + if x != nil && x.NoSparse != nil { + return *x.NoSparse + } + return false +} + +func (x *MapRules) GetKeys() *FieldRules { + if x != nil { + return x.Keys + } + return nil +} + +func (x *MapRules) GetValues() *FieldRules { + if x != nil { + return x.Values + } + return nil +} + +func (x *MapRules) GetIgnoreEmpty() bool { + if x != nil && x.IgnoreEmpty != nil { + return *x.IgnoreEmpty + } + return false +} + +// AnyRules describe constraints applied exclusively to the +// `google.protobuf.Any` well-known type +type AnyRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required specifies that this field must be set + Required *bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` + // In specifies that this field's `type_url` must be equal to one of the + // specified values. + In []string `protobuf:"bytes,2,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field's `type_url` must not be equal to any of + // the specified values. + NotIn []string `protobuf:"bytes,3,rep,name=not_in,json=notIn" json:"not_in,omitempty"` +} + +func (x *AnyRules) Reset() { + *x = AnyRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AnyRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AnyRules) ProtoMessage() {} + +func (x *AnyRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AnyRules.ProtoReflect.Descriptor instead. +func (*AnyRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{20} +} + +func (x *AnyRules) GetRequired() bool { + if x != nil && x.Required != nil { + return *x.Required + } + return false +} + +func (x *AnyRules) GetIn() []string { + if x != nil { + return x.In + } + return nil +} + +func (x *AnyRules) GetNotIn() []string { + if x != nil { + return x.NotIn + } + return nil +} + +// DurationRules describe the constraints applied exclusively to the +// `google.protobuf.Duration` well-known type +type DurationRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required specifies that this field must be set + Required *bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` + // Const specifies that this field must be exactly the specified value + Const *durationpb.Duration `protobuf:"bytes,2,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *durationpb.Duration `protobuf:"bytes,3,opt,name=lt" json:"lt,omitempty"` + // Lt specifies that this field must be less than the specified value, + // inclusive + Lte *durationpb.Duration `protobuf:"bytes,4,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive + Gt *durationpb.Duration `protobuf:"bytes,5,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than the specified value, + // inclusive + Gte *durationpb.Duration `protobuf:"bytes,6,opt,name=gte" json:"gte,omitempty"` + // In specifies that this field must be equal to one of the specified + // values + In []*durationpb.Duration `protobuf:"bytes,7,rep,name=in" json:"in,omitempty"` + // NotIn specifies that this field cannot be equal to one of the specified + // values + NotIn []*durationpb.Duration `protobuf:"bytes,8,rep,name=not_in,json=notIn" json:"not_in,omitempty"` +} + +func (x *DurationRules) Reset() { + *x = DurationRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DurationRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DurationRules) ProtoMessage() {} + +func (x *DurationRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DurationRules.ProtoReflect.Descriptor instead. +func (*DurationRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{21} +} + +func (x *DurationRules) GetRequired() bool { + if x != nil && x.Required != nil { + return *x.Required + } + return false +} + +func (x *DurationRules) GetConst() *durationpb.Duration { + if x != nil { + return x.Const + } + return nil +} + +func (x *DurationRules) GetLt() *durationpb.Duration { + if x != nil { + return x.Lt + } + return nil +} + +func (x *DurationRules) GetLte() *durationpb.Duration { + if x != nil { + return x.Lte + } + return nil +} + +func (x *DurationRules) GetGt() *durationpb.Duration { + if x != nil { + return x.Gt + } + return nil +} + +func (x *DurationRules) GetGte() *durationpb.Duration { + if x != nil { + return x.Gte + } + return nil +} + +func (x *DurationRules) GetIn() []*durationpb.Duration { + if x != nil { + return x.In + } + return nil +} + +func (x *DurationRules) GetNotIn() []*durationpb.Duration { + if x != nil { + return x.NotIn + } + return nil +} + +// TimestampRules describe the constraints applied exclusively to the +// `google.protobuf.Timestamp` well-known type +type TimestampRules struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required specifies that this field must be set + Required *bool `protobuf:"varint,1,opt,name=required" json:"required,omitempty"` + // Const specifies that this field must be exactly the specified value + Const *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=const" json:"const,omitempty"` + // Lt specifies that this field must be less than the specified value, + // exclusive + Lt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=lt" json:"lt,omitempty"` + // Lte specifies that this field must be less than the specified value, + // inclusive + Lte *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=lte" json:"lte,omitempty"` + // Gt specifies that this field must be greater than the specified value, + // exclusive + Gt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=gt" json:"gt,omitempty"` + // Gte specifies that this field must be greater than the specified value, + // inclusive + Gte *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=gte" json:"gte,omitempty"` + // LtNow specifies that this must be less than the current time. LtNow + // can only be used with the Within rule. + LtNow *bool `protobuf:"varint,7,opt,name=lt_now,json=ltNow" json:"lt_now,omitempty"` + // GtNow specifies that this must be greater than the current time. GtNow + // can only be used with the Within rule. + GtNow *bool `protobuf:"varint,8,opt,name=gt_now,json=gtNow" json:"gt_now,omitempty"` + // Within specifies that this field must be within this duration of the + // current time. This constraint can be used alone or with the LtNow and + // GtNow rules. + Within *durationpb.Duration `protobuf:"bytes,9,opt,name=within" json:"within,omitempty"` +} + +func (x *TimestampRules) Reset() { + *x = TimestampRules{} + if protoimpl.UnsafeEnabled { + mi := &file_trpc_validate_validate_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TimestampRules) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TimestampRules) ProtoMessage() {} + +func (x *TimestampRules) ProtoReflect() protoreflect.Message { + mi := &file_trpc_validate_validate_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TimestampRules.ProtoReflect.Descriptor instead. +func (*TimestampRules) Descriptor() ([]byte, []int) { + return file_trpc_validate_validate_proto_rawDescGZIP(), []int{22} +} + +func (x *TimestampRules) GetRequired() bool { + if x != nil && x.Required != nil { + return *x.Required + } + return false +} + +func (x *TimestampRules) GetConst() *timestamppb.Timestamp { + if x != nil { + return x.Const + } + return nil +} + +func (x *TimestampRules) GetLt() *timestamppb.Timestamp { + if x != nil { + return x.Lt + } + return nil +} + +func (x *TimestampRules) GetLte() *timestamppb.Timestamp { + if x != nil { + return x.Lte + } + return nil +} + +func (x *TimestampRules) GetGt() *timestamppb.Timestamp { + if x != nil { + return x.Gt + } + return nil +} + +func (x *TimestampRules) GetGte() *timestamppb.Timestamp { + if x != nil { + return x.Gte + } + return nil +} + +func (x *TimestampRules) GetLtNow() bool { + if x != nil && x.LtNow != nil { + return *x.LtNow + } + return false +} + +func (x *TimestampRules) GetGtNow() bool { + if x != nil && x.GtNow != nil { + return *x.GtNow + } + return false +} + +func (x *TimestampRules) GetWithin() *durationpb.Duration { + if x != nil { + return x.Within + } + return nil +} + +var file_trpc_validate_validate_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 1071, + Name: "trpc.validate.disabled", + Tag: "varint,1071,opt,name=disabled", + Filename: "trpc/validate/validate.proto", + }, + { + ExtendedType: (*descriptorpb.MessageOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 1072, + Name: "trpc.validate.ignored", + Tag: "varint,1072,opt,name=ignored", + Filename: "trpc/validate/validate.proto", + }, + { + ExtendedType: (*descriptorpb.OneofOptions)(nil), + ExtensionType: (*bool)(nil), + Field: 1071, + Name: "trpc.validate.required", + Tag: "varint,1071,opt,name=required", + Filename: "trpc/validate/validate.proto", + }, + { + ExtendedType: (*descriptorpb.FieldOptions)(nil), + ExtensionType: (*FieldRules)(nil), + Field: 1071, + Name: "trpc.validate.rules", + Tag: "bytes,1071,opt,name=rules", + Filename: "trpc/validate/validate.proto", + }, +} + +// Extension fields to descriptorpb.MessageOptions. +var ( + // Disabled nullifies any validation rules for this message, including any + // message fields associated with it that do support validation. + // + // optional bool disabled = 1071; + E_Disabled = &file_trpc_validate_validate_proto_extTypes[0] + // Ignore skips generation of validation methods for this message. + // + // optional bool ignored = 1072; + E_Ignored = &file_trpc_validate_validate_proto_extTypes[1] +) + +// Extension fields to descriptorpb.OneofOptions. +var ( + // Required ensures that exactly one the field options in a oneof is set; + // validation fails if no fields in the oneof are set. + // + // optional bool required = 1071; + E_Required = &file_trpc_validate_validate_proto_extTypes[2] +) + +// Extension fields to descriptorpb.FieldOptions. +var ( + // Rules specify the validations to be performed on this field. By default, + // no validation is performed against a field. + // + // optional trpc.validate.FieldRules rules = 1071; + E_Rules = &file_trpc_validate_validate_proto_extTypes[3] +) + +var File_trpc_validate_validate_proto protoreflect.FileDescriptor + +var file_trpc_validate_validate_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x20, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xb6, 0x09, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x35, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x48, 0x00, 0x52, 0x05, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x64, 0x6f, 0x75, + 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x06, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x12, + 0x31, 0x0a, 0x05, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x49, + 0x6e, 0x74, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x74, + 0x33, 0x32, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x05, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x34, 0x0a, 0x06, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, + 0x73, 0x48, 0x00, 0x52, 0x06, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x34, 0x0a, 0x06, 0x75, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x49, 0x6e, 0x74, + 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x06, 0x75, 0x69, 0x6e, 0x74, 0x36, + 0x34, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x2e, 0x53, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, + 0x06, 0x73, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x74, 0x36, + 0x34, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x37, 0x0a, + 0x07, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, + 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x07, 0x66, + 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x37, 0x0a, 0x07, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, + 0x34, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x07, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, + 0x3a, 0x0a, 0x08, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x65, 0x2e, 0x53, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, + 0x00, 0x52, 0x08, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x12, 0x3a, 0x0a, 0x08, 0x73, + 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x46, + 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x08, 0x73, + 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x12, 0x2e, 0x0a, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, + 0x00, 0x52, 0x04, 0x62, 0x6f, 0x6f, 0x6c, 0x12, 0x34, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x31, 0x0a, + 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x05, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x2e, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x45, + 0x6e, 0x75, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, + 0x12, 0x3a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, + 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x03, + 0x6d, 0x61, 0x70, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x70, 0x63, + 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x4d, 0x61, 0x70, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x61, 0x70, 0x12, 0x2b, 0x0a, 0x03, 0x61, 0x6e, 0x79, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, + 0x00, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x3a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x75, 0x6c, 0x65, 0x73, 0x48, 0x00, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x46, 0x6c, + 0x6f, 0x61, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, + 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x6c, 0x74, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x02, 0x67, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x02, 0x52, 0x03, 0x67, + 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x02, 0x52, 0x02, + 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x02, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb1, 0x01, 0x0a, + 0x0b, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x02, + 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x01, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x01, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x01, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x05, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, + 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x05, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0xb0, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x03, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, + 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x6e, 0x6f, + 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb1, 0x01, 0x0a, 0x0b, 0x55, 0x49, 0x6e, 0x74, 0x33, + 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, + 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, + 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x67, 0x74, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x6e, + 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0d, + 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb1, 0x01, 0x0a, 0x0b, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x6c, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6c, + 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, + 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x04, + 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb1, + 0x01, 0x0a, 0x0b, 0x53, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x11, 0x52, 0x05, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x11, + 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x11, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x11, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x11, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x11, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, + 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x11, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, + 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0xb1, 0x01, 0x0a, 0x0b, 0x53, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x12, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x12, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x12, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x12, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x12, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x12, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, + 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x12, 0x52, 0x05, 0x6e, 0x6f, + 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb2, 0x01, 0x0a, 0x0c, 0x46, 0x69, 0x78, 0x65, 0x64, + 0x33, 0x32, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x07, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, + 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, + 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, + 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x07, 0x52, 0x02, 0x67, 0x74, 0x12, + 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x07, 0x52, 0x03, 0x67, 0x74, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x07, 0x52, 0x02, 0x69, + 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x07, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, + 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb2, 0x01, 0x0a, 0x0c, + 0x46, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x06, 0x52, 0x05, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x06, 0x52, 0x02, + 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x06, 0x52, + 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x06, + 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x06, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x06, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, + 0x18, 0x07, 0x20, 0x03, 0x28, 0x06, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, + 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x53, 0x46, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x52, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0f, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0f, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x03, 0x6c, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x02, 0x67, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0f, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, + 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0f, 0x52, 0x05, 0x6e, 0x6f, + 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb3, 0x01, 0x0a, 0x0d, 0x53, 0x46, 0x69, 0x78, 0x65, + 0x64, 0x36, 0x34, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x10, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x10, 0x52, 0x02, 0x6c, 0x74, 0x12, 0x10, + 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x10, 0x52, 0x03, 0x6c, 0x74, 0x65, + 0x12, 0x0e, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x10, 0x52, 0x02, 0x67, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x67, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x10, 0x52, 0x03, 0x67, + 0x74, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x10, 0x52, 0x02, + 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x10, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x21, 0x0a, 0x09, + 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x22, + 0xd5, 0x06, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x65, 0x6e, 0x18, 0x13, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, + 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, + 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6c, 0x65, 0x6e, + 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6c, 0x65, + 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6e, 0x6f, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, + 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, + 0x5f, 0x69, 0x6e, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, + 0x12, 0x16, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x08, 0x68, 0x6f, + 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x02, 0x69, 0x70, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, + 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14, + 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, + 0x69, 0x70, 0x76, 0x36, 0x12, 0x12, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x08, 0x48, 0x00, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x19, 0x0a, 0x07, 0x75, 0x72, 0x69, 0x5f, + 0x72, 0x65, 0x66, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x06, 0x75, 0x72, 0x69, + 0x52, 0x65, 0x66, 0x12, 0x1a, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x15, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x14, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x45, 0x0a, 0x10, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x65, + 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1e, 0x0a, 0x09, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x00, 0x52, 0x09, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x62, 0x65, 0x74, 0x73, 0x12, 0x1e, 0x0a, 0x09, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x00, 0x52, 0x09, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x09, + 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x08, 0x48, + 0x00, 0x52, 0x09, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x07, + 0x74, 0x73, 0x65, 0x63, 0x73, 0x74, 0x72, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x07, 0x74, 0x73, 0x65, 0x63, 0x73, 0x74, 0x72, 0x12, 0x1c, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, + 0x63, 0x74, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, + 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, + 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x0c, 0x0a, 0x0a, 0x77, 0x65, 0x6c, + 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x22, 0xe2, 0x02, 0x0a, 0x0a, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x6c, 0x65, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x6c, 0x65, 0x6e, 0x12, 0x17, + 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x5f, 0x6c, + 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, + 0x65, 0x66, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, + 0x18, 0x09, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x12, 0x10, 0x0a, + 0x02, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x02, 0x69, 0x70, 0x12, + 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, + 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x14, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x0c, 0x20, + 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x12, 0x21, 0x0a, 0x0c, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x0c, + 0x0a, 0x0a, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x22, 0x6b, 0x0a, 0x09, + 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x6e, + 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x4f, 0x6e, + 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x05, 0x52, 0x02, + 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x05, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x22, 0x3e, 0x0a, 0x0c, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6b, 0x69, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x6b, 0x69, 0x70, 0x12, 0x1a, 0x0a, + 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x22, 0xb5, 0x01, 0x0a, 0x0d, 0x52, 0x65, + 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, + 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x6d, 0x61, 0x78, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x12, 0x2f, 0x0a, + 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, + 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0xe6, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1b, + 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, + 0x61, 0x78, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x6d, 0x61, 0x78, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x73, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x53, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x04, + 0x6b, 0x65, 0x79, 0x73, 0x12, 0x31, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x4d, 0x0a, 0x08, 0x41, 0x6e, + 0x79, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x6e, 0x12, 0x15, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x22, 0xe9, 0x02, 0x0a, 0x0d, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, + 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x2f, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x02, 0x6c, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x6c, 0x74, 0x65, + 0x12, 0x29, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x02, 0x67, 0x74, 0x12, 0x2b, 0x0a, 0x03, 0x67, + 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x07, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x02, 0x69, 0x6e, 0x12, 0x30, 0x0a, 0x06, 0x6e, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, + 0x6e, 0x6f, 0x74, 0x49, 0x6e, 0x22, 0xf3, 0x02, 0x0a, 0x0e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x65, 0x64, 0x12, 0x30, 0x0a, 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x05, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x02, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, + 0x6c, 0x74, 0x12, 0x2c, 0x0a, 0x03, 0x6c, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x6c, 0x74, 0x65, + 0x12, 0x2a, 0x0a, 0x02, 0x67, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x02, 0x67, 0x74, 0x12, 0x2c, 0x0a, 0x03, + 0x67, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x03, 0x67, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x74, + 0x5f, 0x6e, 0x6f, 0x77, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x6c, 0x74, 0x4e, 0x6f, + 0x77, 0x12, 0x15, 0x0a, 0x06, 0x67, 0x74, 0x5f, 0x6e, 0x6f, 0x77, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x67, 0x74, 0x4e, 0x6f, 0x77, 0x12, 0x31, 0x0a, 0x06, 0x77, 0x69, 0x74, 0x68, + 0x69, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2a, 0x46, 0x0a, 0x0a, 0x4b, + 0x6e, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, + 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x48, 0x54, 0x54, 0x50, 0x5f, 0x48, + 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, + 0x48, 0x54, 0x54, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x56, 0x41, 0x4c, 0x55, + 0x45, 0x10, 0x02, 0x3a, 0x3c, 0x0a, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, + 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xaf, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x3a, 0x3a, 0x0a, 0x07, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x1f, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb0, 0x08, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x64, 0x3a, 0x3a, 0x0a, + 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4f, 0x6e, 0x65, 0x6f, + 0x66, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xaf, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x3a, 0x4f, 0x0a, 0x05, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x12, 0x1d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0xaf, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x52, 0x0a, 0x1d, 0x63, 0x6f, + 0x6d, 0x2e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x65, 0x78, 0x74, 0x5a, 0x31, 0x74, 0x72, 0x70, + 0x63, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x74, 0x72, 0x70, + 0x63, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x70, 0x62, 0x2f, 0x67, 0x6f, + 0x2f, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, +} + +var ( + file_trpc_validate_validate_proto_rawDescOnce sync.Once + file_trpc_validate_validate_proto_rawDescData = file_trpc_validate_validate_proto_rawDesc +) + +func file_trpc_validate_validate_proto_rawDescGZIP() []byte { + file_trpc_validate_validate_proto_rawDescOnce.Do(func() { + file_trpc_validate_validate_proto_rawDescData = protoimpl.X.CompressGZIP(file_trpc_validate_validate_proto_rawDescData) + }) + return file_trpc_validate_validate_proto_rawDescData +} + +var file_trpc_validate_validate_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_trpc_validate_validate_proto_msgTypes = make([]protoimpl.MessageInfo, 23) +var file_trpc_validate_validate_proto_goTypes = []interface{}{ + (KnownRegex)(0), // 0: trpc.validate.KnownRegex + (*FieldRules)(nil), // 1: trpc.validate.FieldRules + (*FloatRules)(nil), // 2: trpc.validate.FloatRules + (*DoubleRules)(nil), // 3: trpc.validate.DoubleRules + (*Int32Rules)(nil), // 4: trpc.validate.Int32Rules + (*Int64Rules)(nil), // 5: trpc.validate.Int64Rules + (*UInt32Rules)(nil), // 6: trpc.validate.UInt32Rules + (*UInt64Rules)(nil), // 7: trpc.validate.UInt64Rules + (*SInt32Rules)(nil), // 8: trpc.validate.SInt32Rules + (*SInt64Rules)(nil), // 9: trpc.validate.SInt64Rules + (*Fixed32Rules)(nil), // 10: trpc.validate.Fixed32Rules + (*Fixed64Rules)(nil), // 11: trpc.validate.Fixed64Rules + (*SFixed32Rules)(nil), // 12: trpc.validate.SFixed32Rules + (*SFixed64Rules)(nil), // 13: trpc.validate.SFixed64Rules + (*BoolRules)(nil), // 14: trpc.validate.BoolRules + (*StringRules)(nil), // 15: trpc.validate.StringRules + (*BytesRules)(nil), // 16: trpc.validate.BytesRules + (*EnumRules)(nil), // 17: trpc.validate.EnumRules + (*MessageRules)(nil), // 18: trpc.validate.MessageRules + (*RepeatedRules)(nil), // 19: trpc.validate.RepeatedRules + (*MapRules)(nil), // 20: trpc.validate.MapRules + (*AnyRules)(nil), // 21: trpc.validate.AnyRules + (*DurationRules)(nil), // 22: trpc.validate.DurationRules + (*TimestampRules)(nil), // 23: trpc.validate.TimestampRules + (*durationpb.Duration)(nil), // 24: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp + (*descriptorpb.MessageOptions)(nil), // 26: google.protobuf.MessageOptions + (*descriptorpb.OneofOptions)(nil), // 27: google.protobuf.OneofOptions + (*descriptorpb.FieldOptions)(nil), // 28: google.protobuf.FieldOptions +} +var file_trpc_validate_validate_proto_depIdxs = []int32{ + 18, // 0: trpc.validate.FieldRules.message:type_name -> trpc.validate.MessageRules + 2, // 1: trpc.validate.FieldRules.float:type_name -> trpc.validate.FloatRules + 3, // 2: trpc.validate.FieldRules.double:type_name -> trpc.validate.DoubleRules + 4, // 3: trpc.validate.FieldRules.int32:type_name -> trpc.validate.Int32Rules + 5, // 4: trpc.validate.FieldRules.int64:type_name -> trpc.validate.Int64Rules + 6, // 5: trpc.validate.FieldRules.uint32:type_name -> trpc.validate.UInt32Rules + 7, // 6: trpc.validate.FieldRules.uint64:type_name -> trpc.validate.UInt64Rules + 8, // 7: trpc.validate.FieldRules.sint32:type_name -> trpc.validate.SInt32Rules + 9, // 8: trpc.validate.FieldRules.sint64:type_name -> trpc.validate.SInt64Rules + 10, // 9: trpc.validate.FieldRules.fixed32:type_name -> trpc.validate.Fixed32Rules + 11, // 10: trpc.validate.FieldRules.fixed64:type_name -> trpc.validate.Fixed64Rules + 12, // 11: trpc.validate.FieldRules.sfixed32:type_name -> trpc.validate.SFixed32Rules + 13, // 12: trpc.validate.FieldRules.sfixed64:type_name -> trpc.validate.SFixed64Rules + 14, // 13: trpc.validate.FieldRules.bool:type_name -> trpc.validate.BoolRules + 15, // 14: trpc.validate.FieldRules.string:type_name -> trpc.validate.StringRules + 16, // 15: trpc.validate.FieldRules.bytes:type_name -> trpc.validate.BytesRules + 17, // 16: trpc.validate.FieldRules.enum:type_name -> trpc.validate.EnumRules + 19, // 17: trpc.validate.FieldRules.repeated:type_name -> trpc.validate.RepeatedRules + 20, // 18: trpc.validate.FieldRules.map:type_name -> trpc.validate.MapRules + 21, // 19: trpc.validate.FieldRules.any:type_name -> trpc.validate.AnyRules + 22, // 20: trpc.validate.FieldRules.duration:type_name -> trpc.validate.DurationRules + 23, // 21: trpc.validate.FieldRules.timestamp:type_name -> trpc.validate.TimestampRules + 0, // 22: trpc.validate.StringRules.well_known_regex:type_name -> trpc.validate.KnownRegex + 1, // 23: trpc.validate.RepeatedRules.items:type_name -> trpc.validate.FieldRules + 1, // 24: trpc.validate.MapRules.keys:type_name -> trpc.validate.FieldRules + 1, // 25: trpc.validate.MapRules.values:type_name -> trpc.validate.FieldRules + 24, // 26: trpc.validate.DurationRules.const:type_name -> google.protobuf.Duration + 24, // 27: trpc.validate.DurationRules.lt:type_name -> google.protobuf.Duration + 24, // 28: trpc.validate.DurationRules.lte:type_name -> google.protobuf.Duration + 24, // 29: trpc.validate.DurationRules.gt:type_name -> google.protobuf.Duration + 24, // 30: trpc.validate.DurationRules.gte:type_name -> google.protobuf.Duration + 24, // 31: trpc.validate.DurationRules.in:type_name -> google.protobuf.Duration + 24, // 32: trpc.validate.DurationRules.not_in:type_name -> google.protobuf.Duration + 25, // 33: trpc.validate.TimestampRules.const:type_name -> google.protobuf.Timestamp + 25, // 34: trpc.validate.TimestampRules.lt:type_name -> google.protobuf.Timestamp + 25, // 35: trpc.validate.TimestampRules.lte:type_name -> google.protobuf.Timestamp + 25, // 36: trpc.validate.TimestampRules.gt:type_name -> google.protobuf.Timestamp + 25, // 37: trpc.validate.TimestampRules.gte:type_name -> google.protobuf.Timestamp + 24, // 38: trpc.validate.TimestampRules.within:type_name -> google.protobuf.Duration + 26, // 39: trpc.validate.disabled:extendee -> google.protobuf.MessageOptions + 26, // 40: trpc.validate.ignored:extendee -> google.protobuf.MessageOptions + 27, // 41: trpc.validate.required:extendee -> google.protobuf.OneofOptions + 28, // 42: trpc.validate.rules:extendee -> google.protobuf.FieldOptions + 1, // 43: trpc.validate.rules:type_name -> trpc.validate.FieldRules + 44, // [44:44] is the sub-list for method output_type + 44, // [44:44] is the sub-list for method input_type + 43, // [43:44] is the sub-list for extension type_name + 39, // [39:43] is the sub-list for extension extendee + 0, // [0:39] is the sub-list for field type_name +} + +func init() { file_trpc_validate_validate_proto_init() } +func file_trpc_validate_validate_proto_init() { + if File_trpc_validate_validate_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_trpc_validate_validate_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FieldRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FloatRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DoubleRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Int32Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Int64Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UInt32Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UInt64Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SInt32Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SInt64Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Fixed32Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Fixed64Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SFixed32Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SFixed64Rules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BoolRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StringRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BytesRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EnumRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepeatedRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MapRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AnyRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DurationRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_trpc_validate_validate_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TimestampRules); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_trpc_validate_validate_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*FieldRules_Float)(nil), + (*FieldRules_Double)(nil), + (*FieldRules_Int32)(nil), + (*FieldRules_Int64)(nil), + (*FieldRules_Uint32)(nil), + (*FieldRules_Uint64)(nil), + (*FieldRules_Sint32)(nil), + (*FieldRules_Sint64)(nil), + (*FieldRules_Fixed32)(nil), + (*FieldRules_Fixed64)(nil), + (*FieldRules_Sfixed32)(nil), + (*FieldRules_Sfixed64)(nil), + (*FieldRules_Bool)(nil), + (*FieldRules_String_)(nil), + (*FieldRules_Bytes)(nil), + (*FieldRules_Enum)(nil), + (*FieldRules_Repeated)(nil), + (*FieldRules_Map)(nil), + (*FieldRules_Any)(nil), + (*FieldRules_Duration)(nil), + (*FieldRules_Timestamp)(nil), + } + file_trpc_validate_validate_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*StringRules_Email)(nil), + (*StringRules_Hostname)(nil), + (*StringRules_Ip)(nil), + (*StringRules_Ipv4)(nil), + (*StringRules_Ipv6)(nil), + (*StringRules_Uri)(nil), + (*StringRules_UriRef)(nil), + (*StringRules_Address)(nil), + (*StringRules_Uuid)(nil), + (*StringRules_WellKnownRegex)(nil), + (*StringRules_Alphabets)(nil), + (*StringRules_Alphanums)(nil), + (*StringRules_Lowercase)(nil), + (*StringRules_Tsecstr)(nil), + } + file_trpc_validate_validate_proto_msgTypes[15].OneofWrappers = []interface{}{ + (*BytesRules_Ip)(nil), + (*BytesRules_Ipv4)(nil), + (*BytesRules_Ipv6)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_trpc_validate_validate_proto_rawDesc, + NumEnums: 1, + NumMessages: 23, + NumExtensions: 4, + NumServices: 0, + }, + GoTypes: file_trpc_validate_validate_proto_goTypes, + DependencyIndexes: file_trpc_validate_validate_proto_depIdxs, + EnumInfos: file_trpc_validate_validate_proto_enumTypes, + MessageInfos: file_trpc_validate_validate_proto_msgTypes, + ExtensionInfos: file_trpc_validate_validate_proto_extTypes, + }.Build() + File_trpc_validate_validate_proto = out.File + file_trpc_validate_validate_proto_rawDesc = nil + file_trpc_validate_validate_proto_goTypes = nil + file_trpc_validate_validate_proto_depIdxs = nil +} diff --git a/install/submodules/trpc-protocol/test/BUILD b/install/submodules/trpc-protocol/test/BUILD new file mode 100644 index 0000000..e69de29 diff --git a/install/submodules/trpc-protocol/test/README.md b/install/submodules/trpc-protocol/test/README.md new file mode 100644 index 0000000..95dce0b --- /dev/null +++ b/install/submodules/trpc-protocol/test/README.md @@ -0,0 +1,3 @@ +trpc各语言能正常生成可编译通过代码的测试 + +- cpp:c++语言能正常生成桩代码 diff --git a/install/submodules/trpc-protocol/test/cpp/BUILD b/install/submodules/trpc-protocol/test/cpp/BUILD new file mode 100644 index 0000000..5109206 --- /dev/null +++ b/install/submodules/trpc-protocol/test/cpp/BUILD @@ -0,0 +1,41 @@ +cc_proto_library( + name = "cc_trpc_proto", + deps = [ + "//trpc:trpc_proto", + ], +) + +cc_proto_library( + name = "cc_trpc_options_proto", + deps = [ + "//trpc/proto:trpc_options_proto", + ], +) + +cc_proto_library( + name = "cc_annotations_proto", + deps = [ + "//trpc/api:annotations_proto", + ], +) + +cc_proto_library( + name = "cc_http_proto", + deps = [ + "//trpc/api:http_proto", + ], +) + +cc_proto_library( + name = "cc_swagger_proto", + deps = [ + "//trpc/swagger:swagger_proto", + ], +) + +cc_proto_library( + name = "cc_validate_proto", + deps = [ + "//trpc/validate:validate_proto", + ], +) diff --git a/install/submodules/trpc-protocol/testbuild.sh b/install/submodules/trpc-protocol/testbuild.sh new file mode 100644 index 0000000..a62715c --- /dev/null +++ b/install/submodules/trpc-protocol/testbuild.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +bazel build ... \ No newline at end of file diff --git a/install/submodules/trpc-protocol/trpc/BUILD b/install/submodules/trpc-protocol/trpc/BUILD new file mode 100644 index 0000000..406c1f5 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/BUILD @@ -0,0 +1,8 @@ +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "trpc_proto", + srcs = [ + "trpc.proto", + ], +) diff --git a/install/submodules/trpc-protocol/trpc/api/BUILD b/install/submodules/trpc-protocol/trpc/api/BUILD new file mode 100644 index 0000000..2909d2b --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/api/BUILD @@ -0,0 +1,19 @@ +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "annotations_proto", + srcs = [ + "annotations.proto", + ], + deps = [ + "//trpc/api:http_proto", + "@com_google_protobuf//:descriptor_proto", + ], +) + +proto_library( + name = "http_proto", + srcs = [ + "http.proto", + ], +) diff --git a/install/submodules/trpc-protocol/trpc/api/annotations.proto b/install/submodules/trpc-protocol/trpc/api/annotations.proto new file mode 100644 index 0000000..90a1422 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/api/annotations.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package trpc.api; + +import "trpc/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc/api"; +option java_package = "com.tencent.trpc.protobuf.ext"; + +extend google.protobuf.MethodOptions { + HttpRule http = 50201; +} diff --git a/install/submodules/trpc-protocol/trpc/api/http.proto b/install/submodules/trpc-protocol/trpc/api/http.proto new file mode 100644 index 0000000..b364414 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/api/http.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; + +package trpc.api; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc/api"; +option java_package = "com.tencent.trpc.protobuf.ext"; + +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/install/submodules/trpc-protocol/trpc/proto/BUILD b/install/submodules/trpc-protocol/trpc/proto/BUILD new file mode 100644 index 0000000..6cf0dab --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/proto/BUILD @@ -0,0 +1,11 @@ +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "trpc_options_proto", + srcs = [ + "trpc_options.proto", + ], + deps = [ + "@com_google_protobuf//:descriptor_proto", + ], +) diff --git a/install/submodules/trpc-protocol/trpc/proto/trpc_options.proto b/install/submodules/trpc-protocol/trpc/proto/trpc_options.proto new file mode 100644 index 0000000..0f567aa --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/proto/trpc_options.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; + +package trpc; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc/proto"; +option java_package = "com.tencent.trpc.protobuf.ext"; + +extend google.protobuf.MethodOptions { + string alias = 50001; +} + +extend google.protobuf.FieldOptions { + string go_tag = 50050; +} diff --git a/install/submodules/trpc-protocol/trpc/swagger/BUILD b/install/submodules/trpc-protocol/trpc/swagger/BUILD new file mode 100644 index 0000000..3812bda --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/swagger/BUILD @@ -0,0 +1,11 @@ +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "swagger_proto", + srcs = [ + "swagger.proto", + ], + deps = [ + "@com_google_protobuf//:descriptor_proto", + ], +) diff --git a/install/submodules/trpc-protocol/trpc/swagger/swagger.proto b/install/submodules/trpc-protocol/trpc/swagger/swagger.proto new file mode 100644 index 0000000..85f03a5 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/swagger/swagger.proto @@ -0,0 +1,25 @@ +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; +package trpc; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc/swagger"; +option java_package = "com.tencent.trpc.protobuf.ext"; + +extend google.protobuf.MethodOptions { + SwaggerRule swagger = 50101; +} + +// to gen swagger json +message SwaggerRule { + string title = 50103; + string method = 50104; + string description = 50105; + repeated SwaggerParam params = 50106; +} + +message SwaggerParam { + string name = 1; + bool required = 2; + string default = 3; +} \ No newline at end of file diff --git a/install/submodules/trpc-protocol/trpc/trpc.proto b/install/submodules/trpc-protocol/trpc/trpc.proto new file mode 100644 index 0000000..29ac4b7 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/trpc.proto @@ -0,0 +1,523 @@ +syntax = "proto3"; + +package trpc; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc"; +option java_package = "com.tencent.trpc.proto.standard.common"; +option java_outer_classname = "TRPCProtocol"; + +// The magic value of trpc protocol +enum TrpcMagic { + // trpc does not use this value, it is used by the pb gen-code tool + TRPC_DEFAULT_NONE = 0x00; + + // The magic value used by trpc protocol + TRPC_MAGIC_VALUE = 0x930; +} + +// The data frame type of the trpc protocol packet +// Two types are currently supported: +// 1. The data frame type for unary(one-response-one-response) +// 2. The data frame type for stream +enum TrpcDataFrameType { + TRPC_UNARY_FRAME = 0x00; + + TRPC_STREAM_FRAME = 0x01; +} + +// The specific frame type of trpc streaming data frame +// Four types are currently supported: +// `INIT` frame: FIXHEADER + TrpcStreamInitMeta +// `DATA` frame: FIXHEADER + body (business serialized data) +// `FEEDBACK` frame: FIXHEADER + TrpcStreamFeedBackMeta (triggered strategy: high/low water level and timer) +// `CLOSE` frame: FIXHEADER + TrpcStreamCloseMeta +enum TrpcStreamFrameType { + TRPC_UNARY = 0x00; + + TRPC_STREAM_FRAME_INIT = 0x01; + + TRPC_STREAM_FRAME_DATA = 0x02; + + TRPC_STREAM_FRAME_FEEDBACK = 0x03; + + TRPC_STREAM_FRAME_CLOSE = 0x04; +} + +// The message definition of stream `INIT` frame +message TrpcStreamInitMeta { + // request meta information + TrpcStreamInitRequestMeta request_meta = 1; + + // response meta information + TrpcStreamInitResponseMeta response_meta = 2; + + // The window size is notified by the receiver to the sender + uint32 init_window_size = 3; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 4; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 5; +} + +// The request meta information definition of stream `INIT` frame +message TrpcStreamInitRequestMeta { + // Caller name + // The specification format: trpc.application_name.server_name.proto_service_name, 4 segments + bytes caller = 1; + + // Callee name + // The specification format: trpc.application_name.server_name.proto_service_name[.interface_name] + bytes callee = 2; + + // Interface name of callee + // The specification format: /package.service_name/interface_name + bytes func = 3; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 4; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 5; +}; + +// The response meta information definition of stream `INIT` frame +message TrpcStreamInitResponseMeta { + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 1; + + // The result information when the call fails + bytes error_msg = 2; +}; + +// The meta information definition of stream `FEEDBACK` frame +message TrpcStreamFeedBackMeta { + // increased window size + uint32 window_size_increment = 1; +} + +// The closed type of trpc stream protocol +enum TrpcStreamCloseType { + // normal closes unidirectional flow + TRPC_STREAM_CLOSE = 0; + + // Exception closes bidirectional stream + TRPC_STREAM_RESET = 1; +} + +// The meta information definition of trpc stream protocol for closing stream +message TrpcStreamCloseMeta { + // The type of stream closure, close one end, or close all + int32 close_type = 1; + + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 2; + + // The result information when the call fails + bytes msg = 3; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 4; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 5; + + // The error code of the interface + // 0 means success, other means failure + int32 func_ret = 6; +} + +// The version of trpc protocol +enum TrpcProtoVersion { + TRPC_PROTO_V1 = 0; +} + +// The call type of trpc protocol +enum TrpcCallType { + // Unary(one-response-one-response), include sync and async + TRPC_UNARY_CALL = 0; + + // Oneway + TRPC_ONEWAY_CALL = 1; +} + +// The message type of the transparent transmission information +enum TrpcMessageType { + // trpc does not use this value, it is used by the pb gen-code tool + TRPC_DEFAULT = 0x00; + + // Dyeing message + TRPC_DYEING_MESSAGE = 0x01; + + // Tracing message + TRPC_TRACE_MESSAGE = 0x02; + + // Multi-Environment message + TRPC_MULTI_ENV_MESSAGE = 0x04; + + // grid message + TRPC_GRID_MESSAGE = 0x08; + + // SetNmae message + TRPC_SETNAME_MESSAGE = 0x10; +} + +// The encoding type of the body data in the trpc protocol +// Use proto by default +// At present, it is agreed that the value in the range of 0-127 is used by the framework +enum TrpcContentEncodeType { + // pb + TRPC_PROTO_ENCODE = 0; + + // jce + TRPC_JCE_ENCODE = 1; + + // json + TRPC_JSON_ENCODE = 2; + + // flatbuffer + TRPC_FLATBUFFER_ENCODE = 3; + + // text or binary + TRPC_NOOP_ENCODE = 4; + + // xml + TRPC_XML_ENCODE = 5; + + // thrift + TRPC_THRIFT_ENCODE = 6; +} + +// The compressor type of the body data in the trpc protocol +// No compression by default +enum TrpcCompressType { + // No compression + TRPC_DEFAULT_COMPRESS = 0; + + // gzip + TRPC_GZIP_COMPRESS = 1; + + // snappy(Deprecated) + // please use `TRPC_SNAPPY_STREAM_COMPRESS`/`TRPC_SNAPPY_BLOCK_COMPRESS`, + // Because trpc-go and trpc-cpp use stream and block modes respectively, + // the two are not compatible, and cross-language calls will make mistakes + TRPC_SNAPPY_COMPRESS = 2; + + // zlib + TRPC_ZLIB_COMPRESS = 3; + + // snappy stream + TRPC_SNAPPY_STREAM_COMPRESS = 4; + + // snappy block + TRPC_SNAPPY_BLOCK_COMPRESS = 5; + + // lz4 frame + TRPC_LZ4_FRAME_COMPRESS = 6; + + // lz4 block + TRPC_LZ4_BLOCK_COMPRESS = 7; +} + +// 框架层接口调用的返回码定义 +// The return code definition of the framework layer interface call +enum TrpcRetCode { + // success + TRPC_INVOKE_SUCCESS = 0; + + // server-side error code + // Mainly divided into several categories: + // 1. protocol related, + // 2. interface call related, + // 3. queue timeout or overload related + // 4. ... + + // server-side protocol error code + + // server-side decode error + TRPC_SERVER_DECODE_ERR = 1; + // server-side encode error + TRPC_SERVER_ENCODE_ERR = 2; + + // interface call error code + + // the server-side does not have a corresponding service implementation + TRPC_SERVER_NOSERVICE_ERR = 11; + // the server-side does not have a corresponding interface implementation + TRPC_SERVER_NOFUNC_ERR = 12; + + // timeout/overload/limiter error code + + // the request timed out on the server-side + TRPC_SERVER_TIMEOUT_ERR = 21; + // the request is overloaded on the server-side and the request is discarded + TRPC_SERVER_OVERLOAD_ERR = 22; + // the request is throttled on the server-side + TRPC_SERVER_LIMITED_ERR = 23; + // The request is timed out on the server-side due to the full link timeout + TRPC_SERVER_FULL_LINK_TIMEOUT_ERR = 24; + + // server-side system error + TRPC_SERVER_SYSTEM_ERR = 31; + + // the server-side request authentication failed error + TRPC_SERVER_AUTH_ERR = 41; + + // the server-side request parameter automatic verification failed error + TRPC_SERVER_VALIDATE_ERR = 51; + + // client-side error code + // Mainly divided into several categories: + // 1. timeout related, + // 2. network or connection related, + // 3. protocol related, + // 4. routing related + // 5. ... + + // timeout error code + + // the request is timed out on the client-side + TRPC_CLIENT_INVOKE_TIMEOUT_ERR = 101; + // the request is timed out on the client-side due to the full link timeout + TRPC_CLIENT_FULL_LINK_TIMEOUT_ERR = 102; + + // network or connection error code + + // client-side connection error + TRPC_CLIENT_CONNECT_ERR = 111; + + // protocol error code + + // client-side encode error + TRPC_CLIENT_ENCODE_ERR = 121; + // client-side decode error + TRPC_CLIENT_DECODE_ERR = 122; + + // client-side overload/limter error code + + // the request is throttled on the client-side + TRPC_CLIENT_LIMITED_ERR = 123; + // The request is overloaded on the client-side and discarded + TRPC_CLIENT_OVERLOAD_ERR = 124; + + // service routing error code + TRPC_CLIENT_ROUTER_ERR = 131; + + // client-side network or connection error code + TRPC_CLIENT_NETWORK_ERR = 141; + + // client-side response parameter automatic verification failed error + TRPC_CLIENT_VALIDATE_ERR = 151; + + // upstream actively disconnected, early cancellation request error code + TRPC_CLIENT_CANCELED_ERR = 161; + + // client-side read data frame error + TRPC_CLIENT_READ_FRAME_ERR = 171; + + // error code of the server-side stream + // mainly divided into several categories: + // 1. network or connection related, + // 2. protocol related, + // 3. write stream data related, + // 4. read stream data related, + // 5. ... + + // server-side streaming network or connection error code + TRPC_STREAM_SERVER_NETWORK_ERR = 201; + + // server-side streaming error code + + // stream message exceeds size limit + TRPC_STREAM_SERVER_MSG_EXCEED_LIMIT_ERR = 211; + + // server-side streaming encode error code + TRPC_STREAM_SERVER_ENCODE_ERR = 221; + // server-side streaming decode error code + TRPC_STREAM_SERVER_DECODE_ERR = 222; + + // server-side stream write error code + TRPC_STREAM_SERVER_WRITE_END = 231; + TRPC_STREAM_SERVER_WRITE_OVERFLOW_ERR = 232; + TRPC_STREAM_SERVER_WRITE_CLOSE_ERR = 233; + TRPC_STREAM_SERVER_WRITE_TIMEOUT_ERR = 234; + + // server-side stream read error code + TRPC_STREAM_SERVER_READ_END = 251; + TRPC_STREAM_SERVER_READ_CLOSE_ERR = 252; + TRPC_STREAM_SERVER_READ_EMPTY_ERR = 253; + TRPC_STREAM_SERVER_READ_TIMEOUT_ERR = 254; + + // error code of the client-side stream + // mainly divided into several categories: + // 1. network or connection related, + // 2. protocol related, + // 3. write stream data related, + // 4. read stream data related, + // 5. ... + + // client-side streaming network or connection error code + TRPC_STREAM_CLIENT_NETWORK_ERR = 301; + + // client-side streaming error code + + // client-side stream message exceeds size limit + TRPC_STREAM_CLIENT_MSG_EXCEED_LIMIT_ERR = 311; + + // client-side streaming encode error code + TRPC_STREAM_CLIENT_ENCODE_ERR = 321; + // client-side streaming decode error code + TRPC_STREAM_CLIENT_DECODE_ERR = 322; + + // client-side stream write error code + TRPC_STREAM_CLIENT_WRITE_END = 331; + TRPC_STREAM_CLIENT_WRITE_OVERFLOW_ERR = 332; + TRPC_STREAM_CLIENT_WRITE_CLOSE_ERR = 333; + TRPC_STREAM_CLIENT_WRITE_TIMEOUT_ERR = 334; + + // client-side stream read error code + TRPC_STREAM_CLIENT_READ_END = 351; + TRPC_STREAM_CLIENT_READ_CLOSE_ERR = 352; + TRPC_STREAM_CLIENT_READ_EMPTY_ERR = 353; + TRPC_STREAM_CLIENT_READ_TIMEOUT_ERR = 354; + + // unspecified error code(unary) + TRPC_INVOKE_UNKNOWN_ERR = 999; + // unspecified error code(stream) + TRPC_STREAM_UNKNOWN_ERR = 1000; +} + +// The following key already used by trans_info, be careful not to repeat it: +// "trpc-dyeing-key": dyeing key + +// The request header for unary +message RequestProtocol { + // The version of protocol + // The specific value corresponds to `TrpcProtoVersion` + uint32 version = 1; + + // Call type + // eg: unary, one-way + // The specific value corresponds to `TrpcCallType` + uint32 call_type = 2; + + // The unique id of the request(on the conneciton) + uint32 request_id = 3; + + // The timeout of the request(ms) + uint32 timeout = 4; + + // Caller name + // The specification format: trpc.application_name.server_name.proto_service_name, 4 segments + bytes caller = 5; + + // Callee name + // The specification format: trpc.application_name.server_name.proto_service_name[.interface_name] + bytes callee = 6; + + // Interface name of callee + // The specification format: /package.service_name/interface_name + bytes func = 7; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 8; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + // Note: The key-value pair in trans_info will be transparently transmitted through the whole link, please use it carefully for business. + map trans_info = 9; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 10; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 11; + + // The size of attachment data + uint32 attachment_size = 12; +} + +// The response header for unary +message ResponseProtocol { + // The version of protocol + // The specific value corresponds to `TrpcProtoVersion` + uint32 version = 1; + + // Call type + // eg: unary, one-way + // The specific value corresponds to `TrpcCallType` + uint32 call_type = 2; + + // The unique id of the request(on the conneciton) + uint32 request_id = 3; + + // Error code + // The specific value corresponds to `TrpcRetCode` + int32 ret = 4; + + // The error code of the interface + // 0 means success, other means failure + int32 func_ret = 5; + + // The result information when the call fails + bytes error_msg = 6; + + // The message type of the transparent transmission information + // such as tracing, dyeing key, gray, authentication, multi-environment, set name, etc. + // The specific value corresponds to `TrpcMessageType` + uint32 message_type = 7; + + // The information key-value pair transparently transmitted by the framework + // Currently divided into two parts: + // 1 part is the information to be transparently transmitted by the framework layer, + // and the name of the key must be started with `trpc-`` + // 2 part is the information to be transparently transmitted by the business layer, + // and the business can set it by itself, it is recommended to start with `app-``, not `trpc-` + map trans_info = 8; + + // The serialization type of the request data + // eg: proto/json/.., default proto + // The specific value corresponds to `TrpcContentEncodeType` + uint32 content_type = 9; + + // The compression type of the requested data + // eg: gzip/snappy/..., not used by default + // The specific value corresponds to `TrpcCompressType` + uint32 content_encoding = 10; + + // The size of attachment data + uint32 attachment_size = 12; +} diff --git a/install/submodules/trpc-protocol/trpc/validate/BUILD b/install/submodules/trpc-protocol/trpc/validate/BUILD new file mode 100644 index 0000000..4e2bc91 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/validate/BUILD @@ -0,0 +1,13 @@ +package(default_visibility = ["//visibility:public"]) + +proto_library( + name = "validate_proto", + srcs = [ + "validate.proto", + ], + deps = [ + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:timestamp_proto", + ], +) diff --git a/install/submodules/trpc-protocol/trpc/validate/validate.proto b/install/submodules/trpc-protocol/trpc/validate/validate.proto new file mode 100644 index 0000000..5b91472 --- /dev/null +++ b/install/submodules/trpc-protocol/trpc/validate/validate.proto @@ -0,0 +1,875 @@ +syntax = "proto2"; +package trpc.validate; + +option go_package = "trpc.group/trpc/trpc-protocol/pb/go/trpc/validate"; +option java_package = "com.tencent.trpc.protobuf.ext"; + +import "google/protobuf/descriptor.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// Validation rules applied at the message level +extend google.protobuf.MessageOptions { + // Disabled nullifies any validation rules for this message, including any + // message fields associated with it that do support validation. + optional bool disabled = 1071; + // Ignore skips generation of validation methods for this message. + optional bool ignored = 1072; +} + +// Validation rules applied at the oneof level +extend google.protobuf.OneofOptions { + // Required ensures that exactly one the field options in a oneof is set; + // validation fails if no fields in the oneof are set. + optional bool required = 1071; +} + +// Validation rules applied at the field level +extend google.protobuf.FieldOptions { + // Rules specify the validations to be performed on this field. By default, + // no validation is performed against a field. + optional FieldRules rules = 1071; +} + +// FieldRules encapsulates the rules for each type of field. Depending on the +// field, the correct set should be used to ensure proper validations. +message FieldRules { + optional MessageRules message = 17; + oneof type { + // Scalar Field Types + FloatRules float = 1; + DoubleRules double = 2; + Int32Rules int32 = 3; + Int64Rules int64 = 4; + UInt32Rules uint32 = 5; + UInt64Rules uint64 = 6; + SInt32Rules sint32 = 7; + SInt64Rules sint64 = 8; + Fixed32Rules fixed32 = 9; + Fixed64Rules fixed64 = 10; + SFixed32Rules sfixed32 = 11; + SFixed64Rules sfixed64 = 12; + BoolRules bool = 13; + StringRules string = 14; + BytesRules bytes = 15; + + // Complex Field Types + EnumRules enum = 16; + RepeatedRules repeated = 18; + MapRules map = 19; + + // Well-Known Field Types + AnyRules any = 20; + DurationRules duration = 21; + TimestampRules timestamp = 22; + } +} + +// FloatRules describes the constraints applied to `float` values +message FloatRules { + // Const specifies that this field must be exactly the specified value + optional float const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional float lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional float lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional float gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional float gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated float in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated float not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// DoubleRules describes the constraints applied to `double` values +message DoubleRules { + // Const specifies that this field must be exactly the specified value + optional double const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional double lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional double lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional double gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional double gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated double in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated double not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int32Rules describes the constraints applied to `int32` values +message Int32Rules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Int64Rules describes the constraints applied to `int64` values +message Int64Rules { + // Const specifies that this field must be exactly the specified value + optional int64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional int64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional int64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional int64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional int64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated int64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt32Rules describes the constraints applied to `uint32` values +message UInt32Rules { + // Const specifies that this field must be exactly the specified value + optional uint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// UInt64Rules describes the constraints applied to `uint64` values +message UInt64Rules { + // Const specifies that this field must be exactly the specified value + optional uint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional uint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional uint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional uint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional uint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated uint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated uint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt32Rules describes the constraints applied to `sint32` values +message SInt32Rules { + // Const specifies that this field must be exactly the specified value + optional sint32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SInt64Rules describes the constraints applied to `sint64` values +message SInt64Rules { + // Const specifies that this field must be exactly the specified value + optional sint64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sint64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sint64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sint64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sint64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sint64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sint64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed32Rules describes the constraints applied to `fixed32` values +message Fixed32Rules { + // Const specifies that this field must be exactly the specified value + optional fixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// Fixed64Rules describes the constraints applied to `fixed64` values +message Fixed64Rules { + // Const specifies that this field must be exactly the specified value + optional fixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional fixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional fixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional fixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional fixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated fixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated fixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed32Rules describes the constraints applied to `sfixed32` values +message SFixed32Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed32 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed32 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed32 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed32 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed32 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed32 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed32 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// SFixed64Rules describes the constraints applied to `sfixed64` values +message SFixed64Rules { + // Const specifies that this field must be exactly the specified value + optional sfixed64 const = 1; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional sfixed64 lt = 2; + + // Lte specifies that this field must be less than or equal to the + // specified value, inclusive + optional sfixed64 lte = 3; + + // Gt specifies that this field must be greater than the specified value, + // exclusive. If the value of Gt is larger than a specified Lt or Lte, the + // range is reversed. + optional sfixed64 gt = 4; + + // Gte specifies that this field must be greater than or equal to the + // specified value, inclusive. If the value of Gte is larger than a + // specified Lt or Lte, the range is reversed. + optional sfixed64 gte = 5; + + // In specifies that this field must be equal to one of the specified + // values + repeated sfixed64 in = 6; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated sfixed64 not_in = 7; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 8; +} + +// BoolRules describes the constraints applied to `bool` values +message BoolRules { + // Const specifies that this field must be exactly the specified value + optional bool const = 1; +} + +// StringRules describe the constraints applied to `string` values +message StringRules { + // Const specifies that this field must be exactly the specified value + optional string const = 1; + + // Len specifies that this field must be the specified number of + // characters (Unicode code points). Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 len = 19; + + // MinLen specifies that this field must be the specified number of + // characters (Unicode code points) at a minimum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of + // characters (Unicode code points) at a maximum. Note that the number of + // characters may differ from the number of bytes in the string. + optional uint64 max_len = 3; + + // LenBytes specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 len_bytes = 20; + + // MinBytes specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_bytes = 4; + + // MaxBytes specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_bytes = 5; + + // Pattern specifes that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 6; + + // Prefix specifies that this field must have the specified substring at + // the beginning of the string. + optional string prefix = 7; + + // Suffix specifies that this field must have the specified substring at + // the end of the string. + optional string suffix = 8; + + // Contains specifies that this field must have the specified substring + // anywhere in the string. + optional string contains = 9; + + // NotContains specifies that this field cannot have the specified substring + // anywhere in the string. + optional string not_contains = 23; + + // In specifies that this field must be equal to one of the specified + // values + repeated string in = 10; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated string not_in = 11; + + // WellKnown rules provide advanced constraints against common string + // patterns + oneof well_known { + // Email specifies that the field must be a valid email address as + // defined by RFC 5322 + bool email = 12; + + // Hostname specifies that the field must be a valid hostname as + // defined by RFC 1034. This constraint does not support + // internationalized domain names (IDNs). + bool hostname = 13; + + // Ip specifies that the field must be a valid IP (v4 or v6) address. + // Valid IPv6 addresses should not include surrounding square brackets. + bool ip = 14; + + // Ipv4 specifies that the field must be a valid IPv4 address. + bool ipv4 = 15; + + // Ipv6 specifies that the field must be a valid IPv6 address. Valid + // IPv6 addresses should not include surrounding square brackets. + bool ipv6 = 16; + + // Uri specifies that the field must be a valid, absolute URI as defined + // by RFC 3986 + bool uri = 17; + + // UriRef specifies that the field must be a valid URI as defined by RFC + // 3986 and may be relative or absolute. + bool uri_ref = 18; + + // Address specifies that the field must be either a valid hostname as + // defined by RFC 1034 (which does not support internationalized domain + // names or IDNs), or it can be a valid IP (v4 or v6). + bool address = 21; + + // Uuid specifies that the field must be a valid UUID as defined by + // RFC 4122 + bool uuid = 22; + + // WellKnownRegex specifies a common well known pattern defined as a regex. + KnownRegex well_known_regex = 24; + + // Alphabets specifies that the field can only contain alphabets. e.g. aA + bool alphabets = 27; + + // Alphanums specifies that the field should contain both alphabet(s) and number(s). e.g. aA1 + bool alphanums = 28; + + // Lowercase specifies that the field can only contain lowercase alphabet(s). e.g. aa + bool lowercase = 29; + + // tsecstr specifies that the field can only contain secured strings + bool tsecstr = 30; + } + + // This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable + // strict header validation. + // By default, this is true, and HTTP header validations are RFC-compliant. + // Setting to false will enable a looser validations that only disallows + // \r\n\0 characters, which can be used to bypass header matching rules. + optional bool strict = 25 [default = true]; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 26; +} + +// WellKnownRegex contain some well-known patterns. +enum KnownRegex { + UNKNOWN = 0; + + // HTTP header name as defined by RFC 7230. + HTTP_HEADER_NAME = 1; + + // HTTP header value as defined by RFC 7230. + HTTP_HEADER_VALUE = 2; +} + +// BytesRules describe the constraints applied to `bytes` values +message BytesRules { + // Const specifies that this field must be exactly the specified value + optional bytes const = 1; + + // Len specifies that this field must be the specified number of bytes + optional uint64 len = 13; + + // MinLen specifies that this field must be the specified number of bytes + // at a minimum + optional uint64 min_len = 2; + + // MaxLen specifies that this field must be the specified number of bytes + // at a maximum + optional uint64 max_len = 3; + + // Pattern specifes that this field must match against the specified + // regular expression (RE2 syntax). The included expression should elide + // any delimiters. + optional string pattern = 4; + + // Prefix specifies that this field must have the specified bytes at the + // beginning of the string. + optional bytes prefix = 5; + + // Suffix specifies that this field must have the specified bytes at the + // end of the string. + optional bytes suffix = 6; + + // Contains specifies that this field must have the specified bytes + // anywhere in the string. + optional bytes contains = 7; + + // In specifies that this field must be equal to one of the specified + // values + repeated bytes in = 8; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated bytes not_in = 9; + + // WellKnown rules provide advanced constraints against common byte + // patterns + oneof well_known { + // Ip specifies that the field must be a valid IP (v4 or v6) address in + // byte format + bool ip = 10; + + // Ipv4 specifies that the field must be a valid IPv4 address in byte + // format + bool ipv4 = 11; + + // Ipv6 specifies that the field must be a valid IPv6 address in byte + // format + bool ipv6 = 12; + } + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 14; +} + +// EnumRules describe the constraints applied to enum values +message EnumRules { + // Const specifies that this field must be exactly the specified value + optional int32 const = 1; + + // DefinedOnly specifies that this field must be only one of the defined + // values for this enum, failing on any undefined value. + optional bool defined_only = 2; + + // In specifies that this field must be equal to one of the specified + // values + repeated int32 in = 3; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated int32 not_in = 4; +} + +// MessageRules describe the constraints applied to embedded message values. +// For message-type fields, validation is performed recursively. +message MessageRules { + // Skip specifies that the validation rules of this field should not be + // evaluated + optional bool skip = 1; + + // Required specifies that this field must be set + optional bool required = 2; +} + +// RepeatedRules describe the constraints applied to `repeated` values +message RepeatedRules { + // MinItems specifies that this field must have the specified number of + // items at a minimum + optional uint64 min_items = 1; + + // MaxItems specifies that this field must have the specified number of + // items at a maximum + optional uint64 max_items = 2; + + // Unique specifies that all elements in this field must be unique. This + // contraint is only applicable to scalar and enum types (messages are not + // supported). + optional bool unique = 3; + + // Items specifies the contraints to be applied to each item in the field. + // Repeated message fields will still execute validation against each item + // unless skip is specified here. + optional FieldRules items = 4; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 5; +} + +// MapRules describe the constraints applied to `map` values +message MapRules { + // MinPairs specifies that this field must have the specified number of + // KVs at a minimum + optional uint64 min_pairs = 1; + + // MaxPairs specifies that this field must have the specified number of + // KVs at a maximum + optional uint64 max_pairs = 2; + + // NoSparse specifies values in this field cannot be unset. This only + // applies to map's with message value types. + optional bool no_sparse = 3; + + // Keys specifies the constraints to be applied to each key in the field. + optional FieldRules keys = 4; + + // Values specifies the constraints to be applied to the value of each key + // in the field. Message values will still have their validations evaluated + // unless skip is specified here. + optional FieldRules values = 5; + + // IgnoreEmpty specifies that the validation rules of this field should be + // evaluated only if the field is not empty + optional bool ignore_empty = 6; +} + +// AnyRules describe constraints applied exclusively to the +// `google.protobuf.Any` well-known type +message AnyRules { + // Required specifies that this field must be set + optional bool required = 1; + + // In specifies that this field's `type_url` must be equal to one of the + // specified values. + repeated string in = 2; + + // NotIn specifies that this field's `type_url` must not be equal to any of + // the specified values. + repeated string not_in = 3; +} + +// DurationRules describe the constraints applied exclusively to the +// `google.protobuf.Duration` well-known type +message DurationRules { + // Required specifies that this field must be set + optional bool required = 1; + + // Const specifies that this field must be exactly the specified value + optional google.protobuf.Duration const = 2; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional google.protobuf.Duration lt = 3; + + // Lt specifies that this field must be less than the specified value, + // inclusive + optional google.protobuf.Duration lte = 4; + + // Gt specifies that this field must be greater than the specified value, + // exclusive + optional google.protobuf.Duration gt = 5; + + // Gte specifies that this field must be greater than the specified value, + // inclusive + optional google.protobuf.Duration gte = 6; + + // In specifies that this field must be equal to one of the specified + // values + repeated google.protobuf.Duration in = 7; + + // NotIn specifies that this field cannot be equal to one of the specified + // values + repeated google.protobuf.Duration not_in = 8; +} + +// TimestampRules describe the constraints applied exclusively to the +// `google.protobuf.Timestamp` well-known type +message TimestampRules { + // Required specifies that this field must be set + optional bool required = 1; + + // Const specifies that this field must be exactly the specified value + optional google.protobuf.Timestamp const = 2; + + // Lt specifies that this field must be less than the specified value, + // exclusive + optional google.protobuf.Timestamp lt = 3; + + // Lte specifies that this field must be less than the specified value, + // inclusive + optional google.protobuf.Timestamp lte = 4; + + // Gt specifies that this field must be greater than the specified value, + // exclusive + optional google.protobuf.Timestamp gt = 5; + + // Gte specifies that this field must be greater than the specified value, + // inclusive + optional google.protobuf.Timestamp gte = 6; + + // LtNow specifies that this must be less than the current time. LtNow + // can only be used with the Within rule. + optional bool lt_now = 7; + + // GtNow specifies that this must be greater than the current time. GtNow + // can only be used with the Within rule. + optional bool gt_now = 8; + + // Within specifies that this field must be within this duration of the + // current time. This constraint can be used alone or with the LtNow and + // GtNow rules. + optional google.protobuf.Duration within = 9; +} \ No newline at end of file diff --git a/install/trpc.yaml b/install/trpc.yaml new file mode 100644 index 0000000..f052e14 --- /dev/null +++ b/install/trpc.yaml @@ -0,0 +1,82 @@ +--- +domain: trpc.group +tpl_file_ext: ".tpl" + +idl: + protobuf: + executable: protoc + version_min: v3.6.0 + version_cmd: "" + artifact_url: "https://github.com/trpc-group/trpc-cmdline/releases/download/v0.0.1-${os}/protoc" + md5: "" + repository: "" + fallback: "please install protoc first, see: https://github.com/protocolbuffers/protobuf" + flatbuffers: + executable: flatc + version_min: "" + version_cmd: "" + artifact_url: "https://github.com/trpc-group/trpc-cmdline/releases/download/v0.0.1-${os}/flatc" + md5: "" + repository: "" + fallback: "please install flatc first, see: https://google.github.io/flatbuffers/flatbuffers_guide_building.html" + +tools: + go: + - executable: protoc-gen-go + version_min: "" + version_cmd: "" + artifact_url: "https://github.com/trpc-group/trpc-cmdline/releases/download/v0.0.1-${os}/protoc-gen-go" + md5: "" + repository: "github.com/golang/protobuf/protoc-gen-go" + fallback: "" + - executable: goimports + version_min: "" + version_cmd: "" + artifact_url: "https://github.com/trpc-group/trpc-cmdline/releases/download/v0.0.1-${os}/goimports" + md5: "" + repository: "golang.org/x/tools/cmd/goimports" + fallback: "" + - executable: mockgen + version_min: "" + version_cmd: "" + artifact_url: "https://github.com/trpc-group/trpc-cmdline/releases/download/v0.0.1-${os}/mockgen" + md5: "" + repository: "github.com/golang/mock/mockgen@v1.6.0" + fallback: "" + +plugins: + go: + - swagger + - openapi + - validate + - goimports + - gofmt + - mockgen + - gotag + cpp: + - cpp_move + +templates: + protobuf: + go: + asset_dir: protobuf/asset_go + lang_file_ext: go + separator: "." + keep_orig_name: true + rpc_server_stub: service_rpc.go.tpl + rpc_server_test_stub: service_rpc_test.go.tpl + rpc_client_stub: + - rpc/trpc.go.tpl + cpp: + asset_dir: protobuf/asset_cpp + keep_orig_name: true + flatbuffers: + go: + asset_dir: flatbuffers/asset_go + lang_file_ext: go + separator: "." + keep_orig_name: true + rpc_server_stub: service_rpc.go.tpl + rpc_server_test_stub: service_rpc_test.go.tpl + rpc_client_stub: + - rpc/trpc.go.tpl diff --git a/install/without_idl/go/hippo/go.mod.tpl b/install/without_idl/go/hippo/go.mod.tpl new file mode 100644 index 0000000..3fe944e --- /dev/null +++ b/install/without_idl/go/hippo/go.mod.tpl @@ -0,0 +1,15 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} diff --git a/install/without_idl/go/hippo/main.go.tpl b/install/without_idl/go/hippo/main.go.tpl new file mode 100644 index 0000000..7dd1b1e --- /dev/null +++ b/install/without_idl/go/hippo/main.go.tpl @@ -0,0 +1,36 @@ + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +package main + +import ( + _ "{{$domainName}}/{{$groupName}}/trpc-filter/debuglog{{$versionSuffix}}" + _ "{{$domainName}}/{{$groupName}}/trpc-filter/recovery{{$versionSuffix}}" + _ "go.uber.org/automaxprocs" + + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + "{{$domainName}}/{{$groupName}}/trpc-database/hippo{{$versionSuffix}}" +) + +func main() { + s := trpc.NewServer() + + hippo.RegisterHandlerService(s, handle) + + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} + +func handle(ctx context.Context, message *hippo.Message) error { + return nil +} diff --git a/install/without_idl/go/hippo/trpc_go.yaml b/install/without_idl/go/hippo/trpc_go.yaml new file mode 100644 index 0000000..aa7a3be --- /dev/null +++ b/install/without_idl/go/hippo/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/install/without_idl/go/http/go.mod.tpl b/install/without_idl/go/http/go.mod.tpl new file mode 100644 index 0000000..3fe944e --- /dev/null +++ b/install/without_idl/go/http/go.mod.tpl @@ -0,0 +1,15 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} diff --git a/install/without_idl/go/http/main.go.tpl b/install/without_idl/go/http/main.go.tpl new file mode 100644 index 0000000..7efdfc0 --- /dev/null +++ b/install/without_idl/go/http/main.go.tpl @@ -0,0 +1,37 @@ + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +package main + +import ( + _ "{{$domainName}}/{{$groupName}}/trpc-filter/debuglog{{$versionSuffix}}" + _ "{{$domainName}}/{{$groupName}}/trpc-filter/recovery{{$versionSuffix}}" + _ "go.uber.org/automaxprocs" + + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + thttp "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/http" +) + +func main() { + s := trpc.NewServer() + + thttp.HandleFunc("/", handle) + thttp.RegisterDefaultService(s) + + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} + +func handle(w http.ResponseWriter, r *http.Request) error { + return nil +} diff --git a/install/without_idl/go/http/trpc_go.yaml b/install/without_idl/go/http/trpc_go.yaml new file mode 100644 index 0000000..aa7a3be --- /dev/null +++ b/install/without_idl/go/http/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/install/without_idl/go/kafka/go.mod.tpl b/install/without_idl/go/kafka/go.mod.tpl new file mode 100644 index 0000000..3fe944e --- /dev/null +++ b/install/without_idl/go/kafka/go.mod.tpl @@ -0,0 +1,15 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} diff --git a/install/without_idl/go/kafka/main.go.tpl b/install/without_idl/go/kafka/main.go.tpl new file mode 100644 index 0000000..3714a0a --- /dev/null +++ b/install/without_idl/go/kafka/main.go.tpl @@ -0,0 +1,36 @@ + +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +package main + +import ( + _ "{{$domainName}}/{{$groupName}}/trpc-filter/debuglog{{$versionSuffix}}" + _ "{{$domainName}}/{{$groupName}}/trpc-filter/recovery{{$versionSuffix}}" + _ "go.uber.org/automaxprocs" + + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + "{{$domainName}}/{{$groupName}}/trpc-database/kafka{{$versionSuffix}}" +) + +func main() { + s := trpc.NewServer() + + kafka.RegisterHandlerService(s, handle) + + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} + +func handle(ctx context.Context, key, value []byte, topic string, partition int32, offset int64) error { + return nil +} diff --git a/install/without_idl/go/kafka/trpc_go.yaml b/install/without_idl/go/kafka/trpc_go.yaml new file mode 100644 index 0000000..aa7a3be --- /dev/null +++ b/install/without_idl/go/kafka/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: tcp # Network listening type: tcp or udp. + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/install/without_idl/go/timer/go.mod.tpl b/install/without_idl/go/timer/go.mod.tpl new file mode 100644 index 0000000..3fe944e --- /dev/null +++ b/install/without_idl/go/timer/go.mod.tpl @@ -0,0 +1,15 @@ +{{- $pkgName := .PackageName -}} +{{- $svrName := (index .Services 0).Name -}} + +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} + +{{- if eq .GoMod "" -}} +module trpc.app.{{$svrName}} +{{- else -}} +module {{.GoMod}} +{{- end }} + +go {{.GoVersion}} diff --git a/install/without_idl/go/timer/main.go.tpl b/install/without_idl/go/timer/main.go.tpl new file mode 100644 index 0000000..5ef57cc --- /dev/null +++ b/install/without_idl/go/timer/main.go.tpl @@ -0,0 +1,36 @@ +{{ $domainName := .Domain }} +{{ $groupName := .GroupName }} +{{ $versionSuffix := .VersionSuffix }} + +{{- $pkgName := .PackageName -}} +{{- $goPkgOption := "" -}} +{{- with .FileOptions.go_package -}} + {{- $goPkgOption = . -}} +{{- end -}} +package main + +import ( + _ "{{$domainName}}/{{$groupName}}/trpc-filter/debuglog{{$versionSuffix}}" + _ "{{$domainName}}/{{$groupName}}/trpc-filter/recovery{{$versionSuffix}}" + _ "go.uber.org/automaxprocs" + + "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}/log" + + trpc "{{$domainName}}/{{$groupName}}/trpc-go{{$versionSuffix}}" + "{{$domainName}}/{{$groupName}}/trpc-database/timer{{$versionSuffix}}" +) + +func main() { + s := trpc.NewServer() + + timer.RegisterHandlerService(s, handle) + + if err := s.Serve(); err != nil { + log.Fatal(err) + } +} + +func handle(ctx context.Context) error { + println("hello trpc!") + return nil +} diff --git a/install/without_idl/go/timer/trpc_go.yaml b/install/without_idl/go/timer/trpc_go.yaml new file mode 100644 index 0000000..599b991 --- /dev/null +++ b/install/without_idl/go/timer/trpc_go.yaml @@ -0,0 +1,71 @@ +{{- $pkgName := .PackageName -}} +{{- $sevriceName := (index .Services 0).Name -}} +{{- $sevriceProtocol := .Protocol -}} +{{- $appName := .AppName -}} +{{- $serverName := .ServerName -}} +global: # Global configuration. + namespace: Development # Environment type, either Production or Development. + env_name: test # Environment name for non-production environments. + +server: # Server configuration. + app: {{if $appName}}{{$appName}}{{else}}yourAppName{{end}} # Application name for the business. + server: {{ if $serverName -}} + {{- $serverName -}} + {{- else -}} + {{- $sevriceName -}} + {{- end}} # Process server name. + bin_path: /usr/local/trpc/bin/ # Path to binary executable files and framework configuration files. + conf_path: /usr/local/trpc/conf/ # Path to business configuration files. + data_path: /usr/local/trpc/data/ # Path to business data files. + filter: # List of interceptors for all service handler functions. + - simpledebuglog + - recovery # Intercept panics from business processing goroutines created by the framework. + service: # Services provided by the business, can have multiple. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Route name for the service. + ip: 127.0.0.1 # Service listening IP address, can use placeholder ${ip}. Use either ip or nic, ip takes priority. + # nic: eth0 + port: {{add 8000 $index}} # Service listening port, can use placeholder ${port}. + network: "*/1 * * * * * ?startAtOnce=1" # Timer cron expression: [second minute hour day month weekday] such as "0 */5 * * * *" every 5 minutes + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + timeout: 1000 # Maximum processing time for requests in milliseconds. + {{ end }} + +client: # Backend configuration for client calls. + timeout: 1000 # Maximum processing time for all backends. + namespace: Development # Environment for all backends. + filter: # List of interceptors for all backend function calls. + - simpledebuglog + service: # Configuration for individual backends. + {{range $index, $service := .Services}} + {{- $serviceName := $service.Name -}} + - name: {{if and $appName $serverName -}} + trpc.{{$appName}}.{{$serverName}}.{{$serviceName -}} + {{- else -}} + {{- $pkgName}}.{{$serviceName -}} + {{- end }} # Service name for the backend. + namespace: Development # Environment for the backend. + network: tcp # Network type for the backend: tcp or udp (configuration takes priority). + protocol: {{$sevriceProtocol}} # Application layer protocol: trpc or http. + target: ip://127.0.0.1:{{add 8000 $index}} # Service address for requests. + timeout: 1000 # Maximum processing time for requests. + {{ end }} + +plugins: # Plugin configuration. + log: # Log configuration. + default: # Default log configuration, supports multiple outputs. + - writer: console # Console standard output (default). + level: debug # Log level for standard output. + - writer: file # Local file log. + level: info # Log level for local file rolling logs. + writer_config: + filename: ./trpc.log # Path to store local file rolling logs. + max_size: 10 # Maximum size of local file rolling logs in MB. + max_backups: 10 # Maximum number of log files. + max_age: 7 # Maximum number of days to keep logs. + compress: false # Whether to compress log files. diff --git a/params/option.go b/params/option.go new file mode 100755 index 0000000..5cca0d9 --- /dev/null +++ b/params/option.go @@ -0,0 +1,95 @@ +// Package params stores the parsed parameter data of the tool. +package params + +import ( + "trpc.group/trpc-go/trpc-cmdline/config" +) + +// Option command option. +type Option struct { + // pb/flatbuffers option + Protodirs []string // protofile/flatbuffers import path + Protofile string // protofile/flatbuffers file + ProtofileAbs string // protofile/flatbuffers absolute path + + UseBaseName bool // Whether to pass protoc/flatc by the basename of "--protofile/--fbs" (default as true) + + AliasOn bool // Parses the MethodOption or the "//@alias=" alias in comments to replace the RPC in the .proto file. + PerMethod bool // Whether to support splitting files by method. + OutputDir string // Project output path. + Force bool // Force write. + + DescriptorSetIn string // Descriptor file specified by "--descriptor_set_in". + + // template option + Assetdir string // Service template path. + Language string // Development language, such as Go. + Protocol string // Protocol type, such as trpc, HTTP, etc. + IDLType config.IDLType // IDL file type, such as protobuf, flatbuffers, etc. + RPCOnly bool // Generate only RPC-related code, rather than a complete project. + // Whether to generate dependent stub code, defaults to false. Only effective when RPCOnly is true. + DependencyStub bool + NoGoMod bool // Do not generate go.mod in the stub code, defaults to false. + + // gomod option + GoMod string // go.mod specified in the current project. + GoModEx string // Module extracted from go.mod. + GoVersion string // Specify Go version. + TRPCGoVersion string // Specify trpc-go version. + + // logging option + Verbose bool // Output verbose log information. + + // Mockgen whether to generate mockgen stub. + Mockgen bool + + // Gotag custom go tag by protobuf field options. + Gotag bool + + // KeepOrigRPCName keeps the original RPC name. + KeepOrigRPCName bool + + // OtherType code generation without IDL files, such as Kafka, HTTP. + OtherType string + + // Domain name for the generated code address. + Domain string + // Group name for the generated code address. + GroupName string + // Version suffix for the generated code address (effective for both the main library and dependencies). + VersionSuffix string + + // Supports importing multiple versions of protocols; for example: xxx/v1/runtime;runtime. + MultiVersion bool + + // Whether the generated Go stub code's Service Descriptor naming includes the "Service" suffix. + // Default is to include it. + NoServiceSuffix bool + + // Parsing the Swagger from MethodOption. + SwaggerOn bool + // Use JSON request body instead of query method. + // Use JSON request body instead of the query way. + SwaggerOptJSONParam bool + // Output file name. + SwaggerOut string + + // Parsing the OpenAPI from MethodOption. + OpenAPIOn bool + // Output file name. + OpenAPIOut string + + // Sort the API documentation according to the order defined in the protobuf. + OrderByPBName bool + + // Whether to synchronize the Git repository. + Sync bool + // If Sync is true, push to the remote Git repository address. + // The default is the address specified in the "go_package" option of the .proto file. + Remote string + // Whether to tag the uploaded repository. + NewTag bool + // If Sync is true, set the Git tag. If not specified, the default is in the format "v1.1.1", + // with the latest tag incremented by 1, and carried over in base 100. + Tag string +} diff --git a/parser/fill.go b/parser/fill.go new file mode 100755 index 0000000..d90f9e2 --- /dev/null +++ b/parser/fill.go @@ -0,0 +1,749 @@ +package parser + +import ( + "encoding/json" + "errors" + "fmt" + "go/token" + "sort" + "strings" + + "github.com/jhump/protoreflect/desc" + "go.uber.org/multierr" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + annotations "trpc.group/trpc/trpc-protocol/pb/go/trpc/api" + trpc "trpc.group/trpc/trpc-protocol/pb/go/trpc/proto" + "trpc.group/trpc/trpc-protocol/pb/go/trpc/swagger" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +const ( + Trpc = "trpc" +) + +func fillDependencies(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + // package name, such as "trpc.group/trpcprotocol/testapp/testserver + pb2ValidGoPkg := map[string]string{} // k=pb file name,v=package name processed by protoc + pkg2ValidGoPkg := map[string]string{} // k=pb file package directive, v=package name processed by protoc + pkg2ImportPath := map[string]string{} // k=pb file package directive, v=importpath in go code + pb2ImportPath := map[string]string{} // k=pb file name,v=importpath in go code + pb2DepsPbs := make(map[string][]string) + var err error + func() { + // Provide examples for two different cases. + // 1. No go_package field in file option + // validGoPkg = "trpc_testapp_testserver" // Replace '.' with '_' + // importPath = "trpc.testapp.testserver" // The value of "package"(protobuf) or "namespace"(flatbuffers). + // 2. There is a go_package field in file option. + // validGoPkg = "testserver" // Get the part after the last forward slash in the "go_package" field. + // importPath = "trpc.group/trpcprotocol/testapp/testserver" // Value of the "go_package" field. + validGoPkg := lang.PBValidGoPackage(fd.GetPackage()) + importPath := fd.GetPackage() + if opts := fd.GetFileOptions(); opts != nil { + if gopkgopt := opts.GetGoPackage(); len(gopkgopt) != 0 { + validGoPkg = lang.PBValidGoPackage(gopkgopt) + importPath = gopkgopt + err = multierr.Append(err, checkGoKeyword(fd.GetName(), importPath, validGoPkg)) + } + } + pb2ValidGoPkg[fd.GetName()] = validGoPkg + pb2ImportPath[fd.GetName()] = importPath + }() + var f func(descriptor.Desc) + f = func(fd descriptor.Desc) { + pbName := fd.GetName() + pb2DepsPbs[pbName] = []string{} + for _, dep := range fd.GetDependencies() { + if len(dep.GetDependencies()) != 0 { + f(dep) + } else { + pb2DepsPbs[dep.GetName()] = []string{} + } + fname := dep.GetFullyQualifiedName() + pkg := dep.GetPackage() + pkg2ImportPath[pkg] = pkg + pb2ValidGoPkg[fname] = lang.PBValidGoPackage(pkg) + var ( + validGoPkg = lang.PBValidGoPackage(pkg) + importPath = pkg + ) + if opts := dep.GetFileOptions(); opts != nil { + if gopkgopt := opts.GetGoPackage(); len(gopkgopt) != 0 { + validGoPkg = lang.PBValidGoPackage(gopkgopt) + importPath = gopkgopt + err = multierr.Append(err, checkGoKeyword(dep.GetName(), importPath, validGoPkg)) + } + } + pb2ValidGoPkg[fname] = validGoPkg + pkg2ImportPath[pkg] = importPath + pkg2ValidGoPkg[pkg] = validGoPkg + pb2ImportPath[fname] = importPath + pb2DepsPbs[pbName] = append(pb2DepsPbs[pbName], fname) + } + } + f(fd) + nfd.Pb2ValidGoPkg = pb2ValidGoPkg + nfd.Pkg2ValidGoPkg = pkg2ValidGoPkg + nfd.Pkg2ImportPath = pkg2ImportPath + nfd.Pb2ImportPath = pb2ImportPath + nfd.Pb2DepsPbs = pb2DepsPbs + return err +} + +func checkGoKeyword(file, goPackage, pkgName string) error { + if token.IsKeyword(pkgName) { + return fmt.Errorf("please do not use go keyword `%s` as package name in go_package `%s`, file: `%s`", + pkgName, goPackage, file) + } + return nil +} + +func fillPackageName(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + nfd.PackageName = fd.GetPackage() + return nil +} + +func fillAppServerName(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + strs := strings.Split(fd.GetPackage(), ".") + // Needs to meet the package format, i.e. trpc.{appName}.{ServerName}. + if len(strs) == 3 && strs[0] == Trpc { + nfd.AppName = strs[1] + nfd.ServerName = strs[2] + } + return nil +} + +func fillImports(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + nfd.Imports, nfd.ImportsX = getImports(fd, nfd) + return nil +} + +func fillFileOptions(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + m, err := buildFileOptions(fd.GetFileOptions()) + if err != nil { + return err + } + nfd.FileOptions = m + if pkg, ok := m["go_package"]; ok { + var ok bool + if nfd.GoPackage, ok = pkg.(string); ok { + importName, _ := lang.ExplodeImport(nfd.GoPackage) + nfd.BaseGoPackageName = importName + } + return nil + } + nfd.BaseGoPackageName, _ = lang.ExplodeImport(nfd.PackageName) + return nil +} + +func buildFileOptions(opts descriptor.FileOpt) (map[string]interface{}, error) { + if opts == nil { + return nil, nil + } + + v, err := json.Marshal(opts) + if err != nil { + return nil, err + } + + m := make(map[string]interface{}) + + err = json.Unmarshal(v, &m) + if err != nil { + return nil, err + } + return m, nil +} + +func fillServices(fd descriptor.Desc, nfd *descriptor.FileDescriptor, aliasMode bool) error { + // Traverse all RPC services to fill them into "nfd". + for _, sd := range fd.GetServices() { + nsd, err := newServiceDescriptor(fd, sd, aliasMode) + if err != nil { + return err + } + nfd.Services = append(nfd.Services, nsd) + } + return nil +} + +func newServiceDescriptor( + fd descriptor.Desc, + sd descriptor.ServiceDesc, + aliasMode bool, +) (*descriptor.ServiceDescriptor, error) { + nsd := &descriptor.ServiceDescriptor{ + Name: sd.GetName(), + } + for _, m := range sd.GetMethods() { + rpc, rpcxs, err := newRPCDescriptor(fd, sd, m, aliasMode) + if err != nil { + return nil, err + } + nsd.RPC = append(nsd.RPC, rpc) + nsd.RPCx = append(nsd.RPCx, rpcxs...) + } + if err := checkRESTfulAPIInfo(nsd); err != nil { + return nil, err + } + return nsd, nil +} + +func newRPCDescriptor( + fd descriptor.Desc, + sd descriptor.ServiceDesc, + m descriptor.MethodDesc, + aliasMode bool, +) (rpc *descriptor.RPCDescriptor, rpcxs []*descriptor.RPCDescriptor, err error) { + reqOpts, err := buildFileOptions(m.GetInputType().GetFile().GetFileOptions()) + if err != nil { + return nil, nil, err + } + rspOpts, err := buildFileOptions(m.GetOutputType().GetFile().GetFileOptions()) + if err != nil { + return nil, nil, err + } + rpc = &descriptor.RPCDescriptor{ + Name: m.GetName(), + Cmd: m.GetName(), + FullyQualifiedCmd: fmt.Sprintf("/%s.%s/%s", fd.GetPackage(), sd.GetName(), m.GetName()), + RequestType: m.GetInputType().GetFullyQualifiedName(), + ResponseType: m.GetOutputType().GetFullyQualifiedName(), + LeadingComments: strings.Replace( //compatible with go1.11 + strings.TrimSpace(m.GetSourceInfo().GetLeadingComments()), "\n", "\n// ", -1), + TrailingComments: strings.Replace( + strings.TrimSpace(m.GetSourceInfo().GetTrailingComments()), "\n", "\n// ", -1), + ClientStreaming: m.IsClientStreaming(), + ServerStreaming: m.IsServerStreaming(), + RequestTypePkgDirective: m.GetInputType().GetFile().GetPackage(), + ResponseTypePkgDirective: m.GetOutputType().GetFile().GetPackage(), + RequestTypeFileOptions: reqOpts, + ResponseTypeFileOptions: rspOpts, + } + + pmd, ok := m.(*descriptor.ProtoMethodDescriptor) + if !ok { + return rpc, rpcxs, nil + } + + if alias, ok := parseAliasExtension(pmd.MD.GetMethodOptions()); ok { + rpc := *rpc + rpc.FullyQualifiedCmd = alias + rpcxs = append(rpcxs, &rpc) + } + + if aliasMode { + alias, ok, err := parseAliasComment(rpc.LeadingComments, rpc.TrailingComments) + if err != nil { + return nil, nil, err + } + if ok { + rpc := *rpc + rpc.FullyQualifiedCmd = alias + rpcxs = append(rpcxs, &rpc) + } + } + + rpc.SwaggerInfo = *parseSwaggerInfo(pmd.MD, rpc.LeadingComments) + + contents, err := parseRestAPIContents(pmd.MD) + if err != nil { + return nil, nil, err + } + rpc.RESTfulAPIInfo.ContentList = append(rpc.RESTfulAPIInfo.ContentList, contents...) + + return rpc, rpcxs, nil +} + +func parseSwaggerInfo(md *desc.MethodDescriptor, leadingComments string) *descriptor.SwaggerDescriptor { + // If the title is empty, the leading comment defined in RPC will be taken as the title of the method. + altTile := strings.Replace(leadingComments, "\n", "\n// ", -1) + if si, ok := parseSwaggerV1(md.GetMethodOptions(), altTile); ok { + return si + } + return parseSwaggerDefault(altTile) +} + +func parseSwaggerDefault(altTitle string) *descriptor.SwaggerDescriptor { + return &descriptor.SwaggerDescriptor{ + Title: altTitle, + Method: "post", + Description: "", + Params: make(map[string]*descriptor.SwaggerParamDescriptor), + } +} + +func parseSwaggerV1(m protoreflect.ProtoMessage, altTitle string) (*descriptor.SwaggerDescriptor, bool) { + if ok := proto.HasExtension(m, swagger.E_Swagger); !ok { + return nil, false + } + v := proto.GetExtension(m, swagger.E_Swagger) + sr, ok := v.(*swagger.SwaggerRule) + if !ok { + return nil, false + } + return getSwaggerInfo[*swagger.SwaggerParam](sr, altTitle), true +} + +func getSwaggerInfo[ + SP SwaggerParam, SR SwaggerRule[SP], +](swagger SR, altTitle string) *descriptor.SwaggerDescriptor { + var si descriptor.SwaggerDescriptor + if title := strings.TrimSpace(swagger.GetTitle()); len(title) == 0 { + si.Title = altTitle + } else { + si.Title = title + } + si.Description = strings.TrimSpace(swagger.GetDescription()) + if method := strings.TrimSpace(swagger.GetMethod()); len(method) == 0 { + si.Method = "post" // default: POST + } else { + si.Method = method + } + + si.Params = make(map[string]*descriptor.SwaggerParamDescriptor) + for _, param := range swagger.GetParams() { + si.Params[param.GetName()] = &descriptor.SwaggerParamDescriptor{ + Name: param.GetName(), + Required: param.GetRequired(), + Default: param.GetDefault(), + } + } + return &si +} + +func parseRestAPIContents(m *desc.MethodDescriptor) ([]*descriptor.RESTfulAPIContent, error) { + mo := m.GetMethodOptions() + if proto.HasExtension(mo, annotations.E_Http) { + if httpRule, ok := proto.GetExtension(mo, annotations.E_Http).(*annotations.HttpRule); ok { + return parseRestContents(httpRule) + } + } + return nil, nil +} + +func parseRestContents[HR HttpRule[HR]](httpRule HR) ([]*descriptor.RESTfulAPIContent, error) { + var contents []*descriptor.RESTfulAPIContent + for _, hr := range append([]HR{httpRule}, expandAdditionalBindings(httpRule)...) { + content := getRESTfulAPIContent(hr) + if content == nil { + return nil, fmt.Errorf("get restful api content error") + } + contents = append(contents, content) + } + return contents, nil +} + +func expandAdditionalBindings[HR HttpRule[HR]](rule HR) []HR { + var rs []HR + for _, r := range rule.GetAdditionalBindings() { + rs = append(rs, r) + rs = append(rs, expandAdditionalBindings(r)...) + } + return rs +} + +func getRESTfulAPIContent[HR HttpRule[HR]](httpRule HR) *descriptor.RESTfulAPIContent { + method, pathTmpl, err := parseRestMethodPathTmpl(httpRule) + if err != nil { + return nil + } + return &descriptor.RESTfulAPIContent{ + Method: method, + PathTmpl: pathTmpl, + RequestBody: httpRule.GetBody(), + ResponseBody: httpRule.GetResponseBody(), + } +} + +func parseRestMethodPathTmpl[HR HttpRule[HR]](hr HR) (string, string, error) { + switch hr := interface{}(hr).(type) { + case *annotations.HttpRule: + return parseRestMethodPathTmplV1(hr) + default: + panic("never happen") + } +} + +func parseRestMethodPathTmplV1(hr *annotations.HttpRule) (string, string, error) { + switch p := hr.Pattern.(type) { + case *annotations.HttpRule_Get: + return "GET", p.Get, nil + case *annotations.HttpRule_Put: + return "PUT", p.Put, nil + case *annotations.HttpRule_Post: + return "POST", p.Post, nil + case *annotations.HttpRule_Delete: + return "DELETE", p.Delete, nil + case *annotations.HttpRule_Patch: + return "PATCH", p.Patch, nil + case *annotations.HttpRule_Custom: + return p.Custom.Kind, p.Custom.Path, nil + default: + log.Error("unknown RESTful httpRule: %T", hr.Pattern) + return "", "", fmt.Errorf("unknown RESTful httpRule: %T", hr.Pattern) + } +} + +func checkRESTfulAPIInfo(nsd *descriptor.ServiceDescriptor) error { + var rpcList []*descriptor.RPCDescriptor + rpcList = append(rpcList, nsd.RPC...) + + // Get the RESTful Content list. + restfulContentList := getRESTfulContentList(rpcList) + + pathSet := make(map[string]bool) + for _, each := range restfulContentList { + + // Check if the resource is correct. + if _, err := newPathExpression(each.PathTmpl); err != nil { + return fmt.Errorf("invalid RESTful http path: %s, parse error: %v", each.PathTmpl, err) + } + + key := fmt.Sprintf("%s:%s", each.Method, each.PathTmpl) + if pathSet[key] { + // Duplicate RESTful resources + return fmt.Errorf("exist repeated RESTful http path:%s", each) + } + pathSet[key] = true + } + + return nil +} + +// Tokenize a URL path using the slash separator ; the result does not have empty tokens +func tokenizePath(path string) []string { + if "/" == path { + return nil + } + return strings.Split(strings.Trim(path, "/"), "/") +} + +func getRESTfulContentList(rpcList []*descriptor.RPCDescriptor) []*descriptor.RESTfulAPIContent { + var restfulContentList []*descriptor.RESTfulAPIContent + for _, rpc := range rpcList { + if rpc == nil { + continue + } + + restfulContentList = append(restfulContentList, rpc.RESTfulAPIInfo.ContentList...) + } + return restfulContentList +} + +func parseAliasExtension(m protoreflect.ProtoMessage) (string, bool) { + aliasName, ok := gatherAliasExtension(m, trpc.E_Alias) + if ok { + return aliasName, true + } + return "", false +} + +func gatherAliasExtension( + m protoreflect.ProtoMessage, + et protoreflect.ExtensionType, +) (string, bool) { + ok := proto.HasExtension(m, et) + if !ok { + return "", false + } + v := proto.GetExtension(m, et) + s, ok := v.(string) + if !ok { + return "", false + } + if aliasName := strings.TrimSpace(s); len(aliasName) != 0 { + return aliasName, true + } + return "", false +} + +func parseAliasComment(leading, trailing string) (string, bool, error) { + alias, err := parseComment(leading, trailing) + if err == errAnnotationNotFound { + return "", false, nil + } + if err != nil { + return "", false, err + } + return alias, alias != "", nil +} + +// fillRPCMessageTypes: In the stub code, +// mapping relationships between RPC request/response type names and their corresponding Protobuf definitions +// need to be established. +func fillRPCMessageTypes(fd descriptor.Desc, nfd *descriptor.FileDescriptor) error { + def := map[string]string{} + + for _, sd := range fd.GetServices() { + for _, m := range sd.GetMethods() { + if err := fillRPCMessageTypesByMethod(fd, m, def); err != nil { + return err + } + } + } + + if len(def) != 0 { + nfd.RPCMessageType = def + } + return nil +} + +func fillRPCMessageTypesByMethod(fd descriptor.Desc, m descriptor.MethodDesc, def map[string]string) error { + in := m.GetInputType().GetFullyQualifiedName() + out := m.GetOutputType().GetFullyQualifiedName() + + inDefLoc, err := findMessageDefLocation(in, fd) + if err != nil { + return err + } + def[in] = inDefLoc + + outDefLoc, err := findMessageDefLocation(out, fd) + if err != nil { + return err + } + def[out] = outDefLoc + return nil +} + +func findMessageDefLocation(typ string, fd descriptor.Desc) (string, error) { + if s, done := findMessageDefLocationFromMessageType(typ, fd); done { + return s, nil + } + + if s, done := findMessageDefLocationFromDependencies(typ, fd); done { + return s, nil + } + + return "", errors.New("not found") +} + +func findMessageDefLocationFromMessageType(typ string, fd descriptor.Desc) (string, bool) { + for _, t := range fd.GetMessageTypes() { + if t.GetFullyQualifiedName() == typ { + return fd.GetFullyQualifiedName(), true + } + } + return "", false +} + +func findMessageDefLocationFromDependencies(typ string, fd descriptor.Desc) (string, bool) { + for _, dep := range fd.GetDependencies() { + for _, t := range dep.GetMessageTypes() { + if t.GetFullyQualifiedName() == typ { + return dep.GetFullyQualifiedName(), true + } + } + } + return "", false +} + +func getImports(fd descriptor.Desc, nfd *descriptor.FileDescriptor) ([]string, []descriptor.ImportDesc) { + imports := []string{} + // Avoid importing the same package multiple times. + // Goimports can solve the issue of "import but unused", + // but it cannot solve problems like "redeclared as imported package name". + existed := map[string]struct{}{} + importName2Path := map[string]string{} + + // Use placeholders to avoid special cases: + // if the suffix of the "go_package" field defined in the proto file is "proto", + // the package in "*.trpc.go" will be "proto". + // However, if other proto files imported by the proto file have a "go_package" suffix of "proto", + // they can only be numbered starting from "proto1". + name, path := lang.ExplodeImport(nfd.GoPackage) + if name == "proto" { + importName2Path["proto"] = "" + } + // Skip the current go_package path to prevent duplicate import. + existed[path] = struct{}{} + // The "trpc" name has already been occupied by the trpc-go main library, + // so it also needs to be skipped. + importName2Path[Trpc] = "" + for _, dep := range fd.GetDependencies() { + pb := dep.GetName() + pbImport, ok := nfd.Pb2ImportPath[pb] + if !ok { + panic(fmt.Errorf("get import path of %s fail", pb)) + } + _, ok = existed[pbImport] + if ok { // Prevent duplicate imports. + continue + } + imports = append(imports, pbImport) + existed[pbImport] = struct{}{} + importName, importPath := lang.ExplodeImport(pbImport) + v, ok := importName2Path[importName] + // If there is no duplication, the importName can be directly used with the suffix. + if !ok { + importName2Path[importName] = importPath + continue + } + // If there is a duplication, first check if the importpath is completely the same. + if importPath == v { + continue + } + // If there is a duplication and the importpath is different, automatic numbering is required. + // `importName == "proto" && v == ""` indicates the placeholder proto set above. + var seqno int + if !((importName == "proto" || importName == Trpc) && v == "") { + importName2Path[importName+"1"] = v + delete(importName2Path, importName) + seqno = 2 + } else { + seqno = 1 + } + for i := seqno; ; i++ { + k := fmt.Sprintf("%s%d", importName, i) + if _, ok := importName2Path[k]; !ok { + importName2Path[k] = importPath + break + } + } + } + + importsX := []descriptor.ImportDesc{} + for k, v := range importName2Path { + if (k == "proto" || k == Trpc) && v == "" { + continue + } + desc := descriptor.ImportDesc{ + Name: k, + Path: v, + } + importsX = append(importsX, desc) + } + sort.Slice(importsX, func(i, j int) bool { + return importsX[i].Name <= importsX[j].Name + }) + return imports, importsX +} + +// GetPbPackage retrieves the path where the protobuf files are located. +// When a file option (such as go_package) has a corresponding value in fd.FileOptions, +// the returned pbPackage will be in the form of "trpc.group/trpcprotocol/testapp/testserver". +// Otherwise, pbPackage will be in the form of "trpc.testapp.testserver". +func GetPbPackage(fd *descriptor.FileDescriptor, fileOption string) (string, error) { + // fd.PackageName usually takes the form of "trpc.testapp.testserver" + pbPackage := fd.PackageName + // If fileOption is "go_package", + // the resulting pbPackage will be in the format "trpc.group/trpcprotocol/testapp/testserver". + if o := fd.FileOptions[fileOption]; o != nil { + if v := fd.FileOptions[fileOption].(string); len(v) != 0 { + pbPackage = v + } + } + return pbPackage, nil +} + +// GetPackage combines the package directive and option $lang_package to get a valid package name. +// The package directive is like package trpc.testapp.testserver;. +// The option $lang_package is like option go_package="trpc.group/trpcprotocol/testapp/testserver";. +func GetPackage(fd *descriptor.FileDescriptor, language string) (string, error) { + // fileOption such as go_package + fileOption := fmt.Sprintf("%s_package", language) + pbPackage, err := GetPbPackage(fd, fileOption) + if err != nil { + return "", err + } + switch fileOption { + case "go_package": + pbPackage = lang.TrimRight(";", pbPackage) + case "cpp_package": + pbPackage = lang.TrimRight(";", pbPackage) + default: + log.Error("unknown FileOption: %s", fileOption) + } + + return pbPackage, nil +} + +// CheckSECVEnabled checks if validation rules are defined in the pb. +func CheckSECVEnabled(nfd *descriptor.FileDescriptor) bool { + if _, ok := nfd.Pkg2ValidGoPkg["validate"]; ok { + return ok + } + if _, ok := nfd.Pkg2ValidGoPkg["trpc.validate"]; ok { + return ok + } + _, ok := nfd.Pkg2ValidGoPkg["trpc.v2.validate"] + return ok +} + +var errAnnotationNotFound = errors.New("annotation //@alias= not found") + +func parseComment(leading, trailing string) (string, error) { + leadingComment, leadingErr := parseAlias(leading) + trailingComment, trailingErr := parseAlias(trailing) + + if err := checkCommentErr(leadingComment, leadingErr, trailingComment, trailingErr); err != nil { + return "", err + } + + if leadingErr == nil { + return leadingComment, nil + } + return trailingComment, nil +} + +func checkCommentErr(leadingComment string, leadingErr error, trailingComment string, trailingErr error) error { + if leadingErr != nil && trailingErr != nil { + return errAnnotationNotFound + } + + if isCommentDiff(leadingComment, leadingErr, trailingComment, trailingErr) { + return fmt.Errorf("leading and trailing aliases conflict") + } + + return nil +} + +func isCommentDiff(leadingComment string, leadingErr error, trailingComment string, trailingErr error) bool { + return (leadingErr == nil && trailingErr == nil) && (leadingComment != trailingComment) +} + +func parseAlias(comment string) (string, error) { + const marker = "@alias=" + if !strings.Contains(comment, marker) { + return "", fmt.Errorf("annotation alias %s not found in raw comment %s", marker, comment) + } + + const expectSplit = 2 + s := strings.Split(comment, marker) + if len(s) != expectSplit { + return "", fmt.Errorf( + "raw comment %s can be split by annotation alias %s into %d parts, expect %d", + comment, marker, len(s), expectSplit, + ) + } + + if !notDoubleCommented(s[0]) { + return "", fmt.Errorf("candidate alias %s is double commented", s[0]) + } + + alias := strings.TrimSpace(s[1]) + if len(alias) == 0 { + return "", fmt.Errorf("invalid alias after trim space: %s", comment) + } + + if idx := strings.IndexAny(alias, " \n"); idx > 0 { + return alias[:idx], nil + } + return alias, nil +} + +func notDoubleCommented(prefix string) bool { + // Example of prefix: + // Return true: + // `// rpc Hello1(HelloReq) returns(HelloRsp){} \n // ` + // Return false: + // `// rpc Hello1(HelloReq) returns(HelloRsp){} // ` + s := strings.Split(prefix, "//") + return len(s) <= 2 || // Only has one comment line. + strings.Contains(s[len(s)-2], "\n") // Comment line is started on a new line. +} diff --git a/parser/fill_test.go b/parser/fill_test.go new file mode 100644 index 0000000..415015f --- /dev/null +++ b/parser/fill_test.go @@ -0,0 +1,70 @@ +package parser + +import ( + "testing" + + "trpc.group/trpc-go/trpc-cmdline/util/lang" +) + +func Test_explodeImport(t *testing.T) { + tests := []struct { + name string + arg string + wantImportName string + wantImportPath string + }{ + { + name: "/tencent/common", + arg: "/tencent/common", + wantImportName: "common", + wantImportPath: "/tencent/common", + }, + { + name: "trpc.group/tencent/common", + arg: "trpc.group/tencent/common", + wantImportName: "common", + wantImportPath: "trpc.group/tencent/common", + }, + { + name: "trpc.group/tencent/common;xyz", + arg: "trpc.group/tencent/common;xyz", + wantImportName: "xyz", + wantImportPath: "trpc.group/tencent/common", + }, + { + name: "common", + arg: "common", + wantImportName: "common", + wantImportPath: "common", + }, + { + name: "a.b.c.d", + arg: "a.b.c.d", + wantImportName: "a_b_c_d", + wantImportPath: "a.b.c.d", + }, + { + name: "trpc.group/hello/a.b.c.d", + arg: "trpc.group/hello/a.b.c.d", + wantImportName: "a_b_c_d", + wantImportPath: "trpc.group/hello/a.b.c.d", + }, + { + name: "trpc.group/hello/a.b.c.d;xyz", + arg: "trpc.group/hello/a.b.c.d;xyz", + wantImportName: "xyz", + wantImportPath: "trpc.group/hello/a.b.c.d", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotImportName, gotImportPath := lang.ExplodeImport(tt.arg) + if gotImportName != tt.wantImportName { + t.Errorf("explodeImport() gotImportName = %v, want %v", gotImportName, tt.wantImportName) + } + if gotImportPath != tt.wantImportPath { + t.Errorf("explodeImport() gotImportPath = %v, want %v", gotImportPath, tt.wantImportPath) + } + }) + } +} diff --git a/parser/option.go b/parser/option.go new file mode 100644 index 0000000..82701de --- /dev/null +++ b/parser/option.go @@ -0,0 +1,48 @@ +package parser + +type options struct { + aliasOn bool + language string + rpcOnly bool + multiVersion bool +} + +// Option parse option +type Option func(*options) + +// WithAliasOn enable alias +func WithAliasOn(enabled bool) Option { + return func(opts *options) { + if opts != nil { + opts.aliasOn = enabled + } + } +} + +// WithLanguage specify language for further checking +func WithLanguage(lang string) Option { + return func(opts *options) { + if opts != nil { + opts.language = lang + } + } +} + +// WithRPCOnly enable RPC only +func WithRPCOnly(enabled bool) Option { + return func(opts *options) { + if opts != nil { + opts.rpcOnly = enabled + } + } +} + +// WithMultiVersion enable multi-version support. +func WithMultiVersion(enabled bool) Option { + return func(opts *options) { + if opts != nil { + opts.multiVersion = enabled + } + } + +} diff --git a/parser/parser.go b/parser/parser.go new file mode 100644 index 0000000..ad44ada --- /dev/null +++ b/parser/parser.go @@ -0,0 +1,258 @@ +// Package parser provides the ability of the parser to generate IDC descriptions from specified files. +package parser + +import ( + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "strings" + + "github.com/jhump/protoreflect/desc" + "github.com/jhump/protoreflect/desc/protoparse" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/descriptorpb" + + "trpc.group/trpc-go/fbs" + + "github.com/pkg/errors" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +type idlParser func(protofile string, protodirs []string, opts ...Option) (*descriptor.FileDescriptor, error) + +var idlParsers = map[config.IDLType]idlParser{ + config.IDLTypeProtobuf: ParseProtoFile, + config.IDLTypeFlatBuffers: ParseFlatbuffers, +} + +// Parse parses the given file, which can be either a Protocol Buffer or FlatBuffers file. +func Parse(protofile string, dirs []string, typ config.IDLType, opts ...Option) (*descriptor.FileDescriptor, error) { + fn, ok := idlParsers[typ] + if !ok { + return nil, fmt.Errorf("idltype: %v not supported", typ) + } + + fd, err := fn(protofile, dirs, opts...) + if err != nil { + return nil, fmt.Errorf("parse IDL[%s] %s error: %v", typ, protofile, err) + } + return fd, nil +} + +// LoadDescriptorSet loads the file descriptor from the given file name. +func LoadDescriptorSet(descriptorSetInFile, protofile string, opts ...Option) (*descriptor.FileDescriptor, error) { + option := &options{ + aliasOn: false, + language: "go", + rpcOnly: false, + } + for _, o := range opts { + o(option) + } + bytes, err := os.ReadFile(descriptorSetInFile) + if err != nil { + return nil, fmt.Errorf("os.ReadFile load descriptor_set_in err: %w", err) + } + dbpFileDescriptorSet := &descriptorpb.FileDescriptorSet{} + if err := proto.Unmarshal(bytes, dbpFileDescriptorSet); err != nil { + return nil, err + } + fileDescriptorMap, err := desc.CreateFileDescriptors(dbpFileDescriptorSet.File) + if err != nil { + return nil, err + } + d, ok := fileDescriptorMap[protofile] + if !ok { + return nil, fmt.Errorf( + "protofile %s not found in descriptor_set_in file %s", protofile, descriptorSetInFile) + } + wd, err := os.Getwd() + if err != nil { + return nil, fmt.Errorf("os.Getwd err: %w", err) + } + return convertFileDescriptor(path.Join(wd, protofile), nil, &descriptor.ProtoFileDescriptor{FD: d}, option) +} + +// checkRequirements checks if the requirements are met. +// +// requirements: +// - Must specify fileoption go_package, +// and the ending part of the go_package must be consistent with the package directive specified package name; +// - packageName must be equal to serviceName, +// and if there are multiple service definitions, +// only the first service will be processed, and the rest will be ignored; +// - The number of service definitions must not be 0, except for specifying rpconly. + +// ParseProtoFile parses a proto file and returns a constructed FileDescriptor object +// that can be used for template filling. +// +// ParseProtoFile is responsible for: +// - parsing the pb file to get the original description information +// - checking project constraints, such as whether custom constraints such as go_option and method option are specified. +func ParseProtoFile(protofile string, protodirs []string, opts ...Option) (*descriptor.FileDescriptor, error) { + option := &options{ + aliasOn: false, + language: "go", + rpcOnly: false, + } + for _, o := range opts { + o(option) + } + + // Parse pb. + fds, err := parseProtoFile(protofile, protodirs...) + if err != nil { + return nil, fmt.Errorf("parseProtoFile err: %+v", err) + } + return convertFileDescriptor(protofile, protodirs, &descriptor.ProtoFileDescriptor{FD: fds[0]}, option) +} + +func convertFileDescriptor( + protofile string, + protodirs []string, + fd descriptor.Desc, + option *options, +) (*descriptor.FileDescriptor, error) { + // Check constraints. + if err := checkRequirements(fd, option); err != nil { + return nil, err + } + // Construct a FileDescriptor that can be used to guide code generation. + fileDescriptor := &descriptor.FileDescriptor{FD: fd} + // Set dependencies (pb files being imported and their output package names) + mustNilError(fillDependencies(fd, fileDescriptor)) + // Set packageName + mustNilError(fillPackageName(fd, fileDescriptor)) + // Set fileOptions + mustNilError(fillFileOptions(fd, fileDescriptor)) + // Set imports + mustNilError(fillImports(fd, fileDescriptor)) + // Set service + mustNilError(fillServices(fd, fileDescriptor, option.aliasOn)) + // Set app server + mustNilError(fillAppServerName(fd, fileDescriptor)) + // SetMessageTypes sets the definitions of the request and response types of the RPC + mustNilError(fillRPCMessageTypes(fd, fileDescriptor)) + + fileDescriptor.RelatvieFilePath = protofile + if filepath.IsAbs(protofile) { + fileDescriptor.FilePath = protofile + } else { + fp, err := fs.LocateFile(protofile, protodirs) + if err != nil { + return nil, fmt.Errorf("fs.LocateFile err: %w", err) + } + fileDescriptor.FilePath = fp + } + + return fileDescriptor, nil +} + +// parseProtoFile uses jhump/protoreflect to parse the .proto file and retrieve the file descriptor. +func parseProtoFile(fname string, protodirs ...string) ([]*desc.FileDescriptor, error) { + parser := protoparse.Parser{ + ImportPaths: protodirs, + IncludeSourceCodeInfo: true, + } + log.Debug("parseProtoFile: ImportPaths: %+v", protodirs) + return parser.ParseFiles(fname) +} + +func checkRequirements(fd descriptor.Desc, opts *options) error { + // MUST: service + if len(fd.GetServices()) == 0 && !opts.rpcOnly { + return errors.New("service missing") + } + + if !opts.multiVersion { + if err := checkMultiVersion(fd); err != nil { + return err + } + } + return nil +} + +var exemptionProtos = []string{ + "trpc.proto", + "trpc_options.proto", + "validate.proto", + "swagger.proto", + "annotations.proto", + "http.proto", +} + +// checkMultiVersion check if exist multi-version in proto file. +func checkMultiVersion(fd descriptor.Desc) error { + r, err := regexp.Compile(`^.*/v\d$`) + if err != nil { + return err + } + for _, el := range loadImports(fd) { + if matchAny(el.fileName, exemptionProtos) { + continue + } + if ok := r.MatchString(el.importPath); ok { + return fmt.Errorf( + "proto: %s, not supported: go_package=\"%s\""+ + "see: trpc --multi-version param", + el.fileName, el.importPath) + } + } + + return nil +} + +func matchAny(s string, names []string) bool { + for i := range names { + if strings.Contains(s, names[i]) { + return true + } + } + return false +} + +type protodesc struct { + importPath string + fileName string +} + +func loadImports(fd descriptor.Desc) []protodesc { + all := []protodesc{} + _, importPath := lang.ExplodeImport(fd.GetFileOptions().GetGoPackage()) + all = append(all, protodesc{importPath, fd.GetName()}) + + for _, dep := range fd.GetDependencies() { + all = append(all, loadImports(dep)...) + } + return all +} + +// ParseFlatbuffers parses a flatbuffers file and returns a FileDescriptor object that can be used for template filling. +func ParseFlatbuffers(protofile string, protodirs []string, opts ...Option) (*descriptor.FileDescriptor, error) { + option := options{} + for _, o := range opts { + o(&option) + } + + // Parse flatbuffers file. + parser := fbs.NewParser(protodirs...) + fds, err := parser.ParseFiles(protofile) + if err != nil { + return nil, err + } + return convertFileDescriptor(protofile, protodirs, &descriptor.FbsFileDescriptor{FD: fds[0]}, &option) +} + +func mustNilError(err error) { + if err != nil { + log.Error("error encountered: %v", err) + os.Exit(1) + } +} diff --git a/parser/parser_imports_test.go b/parser/parser_imports_test.go new file mode 100644 index 0000000..44890a7 --- /dev/null +++ b/parser/parser_imports_test.go @@ -0,0 +1,53 @@ +package parser + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestParseFile(t *testing.T) { + wd, _ := os.Getwd() + + // The suffix of the go_package field may vary between the proto files and their imported proto files. + // The imported proto files may have the same package but different suffix of go_package. + t.Run("1-suffix of importpath not equal", func(t *testing.T) { + proto := filepath.Join(wd, "testcase/importpath/case1/hello.proto") + dir, file := filepath.Split(proto) + fd, err := ParseProtoFile(file, []string{dir}) + if err != nil { + t.Fatalf("parse proto failed: %v", err) + } + //package: hello + //import: trpc.group/dep/dep1 + //import: trpc.group/dep/dep2 + require.Len(t, fd.ImportsX, 1) + require.Equal(t, "dep1", fd.ImportsX[0].Name) + require.Equal(t, "trpc.group/dep/dep1", fd.ImportsX[0].Path) + }) + + // The package name and the suffix of go_package are different from imported proto files. + // For imported proto files, the package name is the same but the suffix of go_package is different. + t.Run("2-suffix of importpath not equal", func(t *testing.T) { + proto := filepath.Join(wd, "testcase/importpath/case2/hello.proto") + dir, file := filepath.Split(proto) + fd, err := ParseProtoFile(file, []string{dir}) + if err != nil { + t.Fatalf("parse proto failed: %v", err) + } + for _, v := range fd.FD.GetDependencies() { + fmt.Println("import: ", v.GetFileOptions().GetGoPackage()) + } + //package: hello + //import: trpc.group/dep1/proto + //import: trpc.group/dep2/proto + require.Len(t, fd.ImportsX, 2) + require.Equal(t, "proto1", fd.ImportsX[0].Name) + require.Equal(t, "trpc.group/dep1/proto", fd.ImportsX[0].Path) + require.Equal(t, "proto2", fd.ImportsX[1].Name) + require.Equal(t, "trpc.group/dep2/proto", fd.ImportsX[1].Path) + }) +} diff --git a/parser/parser_test.go b/parser/parser_test.go new file mode 100644 index 0000000..fd1c9f5 --- /dev/null +++ b/parser/parser_test.go @@ -0,0 +1,152 @@ +package parser + +import ( + "testing" + + annotations "trpc.group/trpc/trpc-protocol/pb/go/trpc/api" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" +) + +func Test_parseRPCAlias(t *testing.T) { + tests := []struct { + name string + comment string + wantComment string + wantErr bool + }{ + { + name: "1-annotation_ok", + comment: "//@alias=/api/hello", + wantComment: "/api/hello", + wantErr: false, + }, { + name: "2-annotation_ok (with comments)", + comment: "//@alias=/api/hello 其他描述", + wantComment: "/api/hello", + wantErr: false, + }, { + name: "3-annotation_ok (with delimiter)", + comment: "//@alias= /api/hello 其他描述", + wantComment: "/api/hello", + wantErr: false, + }, { + name: "4-annotation_err", + comment: "//@alia= /api/hello 其他描述", + wantComment: "", + wantErr: true, + }, { + name: "5-annotation_err (must occur once)", + comment: "//@alias=/api/hello @alias=/api/hello", + wantComment: "", + wantErr: true, + }, { + name: "6-annotation_err (empty value)", + comment: "//@alias= ", + wantComment: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotComment, err := parseAlias(tt.comment) + if (err != nil) != tt.wantErr { + t.Errorf("getAnnotatedComment() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotComment != tt.wantComment { + t.Errorf("getAnnotatedComment() gotComment = %v, want %v", gotComment, tt.wantComment) + } + }) + } +} + +func Test_parseRPCComment(t *testing.T) { + tests := []struct { + name string + rpc *descriptor.RPCDescriptor + wantComment string + wantErr bool + }{ + { + name: "1-annotation_not_found", + rpc: &descriptor.RPCDescriptor{ + LeadingComments: "//@alia=/api/hello", + TrailingComments: "//@alia=/api/hello", + }, + wantComment: "", + wantErr: true, + }, { + name: "2-annotation_conflict", + rpc: &descriptor.RPCDescriptor{ + LeadingComments: "//@alias=/api/hello1", + TrailingComments: "//@alias=/api/hello2", + }, + wantComment: "", + wantErr: true, + }, { + name: "3-select_valid_annotation (leading)", + rpc: &descriptor.RPCDescriptor{ + LeadingComments: "//@alias=/api/hello", + TrailingComments: "//@alia=/api/hello", + }, + wantComment: "/api/hello", + wantErr: false, + }, { + name: "4-select_valid_annotation (trailing)", + rpc: &descriptor.RPCDescriptor{ + LeadingComments: "//@alia=/api/hello", + TrailingComments: "//@alias=/api/hello", + }, + wantComment: "/api/hello", + wantErr: false, + }, { + name: "5-select_valid_annotation (same)", + rpc: &descriptor.RPCDescriptor{ + LeadingComments: "//@alias=/api/hello", + TrailingComments: "//@alias=/api/hello", + }, + wantComment: "/api/hello", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotComment, err := parseComment(tt.rpc.LeadingComments, tt.rpc.TrailingComments) + if (err != nil) != tt.wantErr { + t.Errorf("getAnnotationValue() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotComment != tt.wantComment { + t.Errorf("getAnnotationValue() gotComment = %v, want %v", gotComment, tt.wantComment) + } + }) + } +} + +func Test_fillMethodRESTfulInfo(t *testing.T) { + tests := []struct { + name string + httpRule *annotations.HttpRule + wantErr bool + }{ + { + name: "case-unknown_RESTful_method", + httpRule: &annotations.HttpRule{ + Selector: "", + Pattern: nil, + Body: "", + ResponseBody: "", + AdditionalBindings: nil, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if _, err := parseRestContents(tt.httpRule); (err != nil) != tt.wantErr { + t.Errorf("fillRESTfulAPIContentMethod() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/parser/path_expr.go b/parser/path_expr.go new file mode 100644 index 0000000..fa4563a --- /dev/null +++ b/parser/path_expr.go @@ -0,0 +1,71 @@ +package parser + +import ( + "bytes" + "fmt" + "regexp" + "strings" +) + +// Path expression. +type pathExpression struct { + LiteralCount int // number of literal chars (means those not resulting from template variable substitution) + VarNames []string // names of parameters (enclosed by {}) in the path + VarCount int // number of named parameters (enclosed by {}) in the path + Matcher *regexp.Regexp + Source string // Path as defined by the RouteBuilder + tokens []string +} + +// newPathExpression parses the path and constructs a REST path expression. +func newPathExpression(path string) (*pathExpression, error) { + expression, literalCount, varNames, varCount, tokens := templateToRE(path) + compiled, err := regexp.Compile(expression) + if err != nil { + return nil, err + } + return &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil +} + +// templateToRE converts a RESTful path to a regular expression. +// See https://github.com/emicklei/go-restful/blob/v3/path_expression_test.go +func templateToRE(template string) (expr string, literalCount int, varNames []string, varCount int, tokens []string) { + var buffer bytes.Buffer + buffer.WriteString("^") + + tokens = tokenizePath(template) + for _, each := range tokens { + if each == "" { + continue + } + + buffer.WriteString("/") + if !strings.HasPrefix(each, "{") { + literalCount += len(each) + encoded := each + buffer.WriteString(regexp.QuoteMeta(encoded)) + continue + } + + // check for regular expression in variable + colon := strings.Index(each, ":") + var varName string + if colon != -1 { + // extract expression + varName = strings.TrimSpace(each[1:colon]) + paramExpr := strings.TrimSpace(each[colon+1 : len(each)-1]) + if paramExpr == "*" { // special case + buffer.WriteString("(.*)") + } else { + buffer.WriteString(fmt.Sprintf("(%s)", paramExpr)) // between colon and closing moustache + } + } else { + // plain var + varName = strings.TrimSpace(each[1 : len(each)-1]) + buffer.WriteString("([^/]+?)") + } + varNames = append(varNames, varName) + varCount++ + } + return strings.TrimRight(buffer.String(), "/") + "(/.*)?$", literalCount, varNames, varCount, tokens +} diff --git a/parser/path_expr_test.go b/parser/path_expr_test.go new file mode 100644 index 0000000..36add99 --- /dev/null +++ b/parser/path_expr_test.go @@ -0,0 +1,45 @@ +package parser + +import ( + "reflect" + "testing" +) + +var tempregexs = []struct { + template, regex string + names []string + literalCount, varCount int +}{ + {"", "^(/.*)?$", nil, 0, 0}, + {"/a/{b}/c/", "^/a/([^/]+?)/c(/.*)?$", []string{"b"}, 2, 1}, + {"/{a}/{b}/{c-d-e}/", "^/([^/]+?)/([^/]+?)/([^/]+?)(/.*)?$", []string{"a", "b", "c-d-e"}, 0, 3}, + {"/{p}/abcde", "^/([^/]+?)/abcde(/.*)?$", []string{"p"}, 5, 1}, + {"/a/{b:*}", "^/a/(.*)(/.*)?$", []string{"b"}, 1, 1}, + {"/a/{b:[a-z]+}", "^/a/([a-z]+)(/.*)?$", []string{"b"}, 1, 1}, +} + +func TestTemplateToRE(t *testing.T) { + ok := true + for i, fixture := range tempregexs { + actual, lCount, varNames, vCount, _ := templateToRE(fixture.template) + if actual != fixture.regex { + t.Logf("regex mismatch, expected:%v , actual:%v, line:%v\n", fixture.regex, actual, i) // 11 = where the data starts + ok = false + } + if lCount != fixture.literalCount { + t.Logf("literal count mismatch, expected:%v , actual:%v, line:%v\n", fixture.literalCount, lCount, i) + ok = false + } + if vCount != fixture.varCount { + t.Logf("variable count mismatch, expected:%v , actual:%v, line:%v\n", fixture.varCount, vCount, i) + ok = false + } + if !reflect.DeepEqual(fixture.names, varNames) { + t.Logf("variable name mismatch, expected:%v , actual:%v, line:%v\n", fixture.names, varNames, i) + ok = false + } + } + if !ok { + t.Fatal("one or more expression did not match") + } +} diff --git a/parser/restful.go b/parser/restful.go new file mode 100644 index 0000000..b72b552 --- /dev/null +++ b/parser/restful.go @@ -0,0 +1,13 @@ +package parser + +import ( + annotations "trpc.group/trpc/trpc-protocol/pb/go/trpc/api" +) + +// HttpRule provide interface for http rule. +type HttpRule[HR any] interface { + *annotations.HttpRule + GetAdditionalBindings() []HR + GetBody() string + GetResponseBody() string +} diff --git a/parser/swagger.go b/parser/swagger.go new file mode 100644 index 0000000..adba8b5 --- /dev/null +++ b/parser/swagger.go @@ -0,0 +1,20 @@ +package parser + +import ( + "trpc.group/trpc/trpc-protocol/pb/go/trpc/swagger" +) + +type SwaggerRule[SP SwaggerParam] interface { + *swagger.SwaggerRule + GetTitle() string + GetDescription() string + GetMethod() string + GetParams() []SP +} + +type SwaggerParam interface { + *swagger.SwaggerParam + GetName() string + GetRequired() bool + GetDefault() string +} diff --git a/parser/testcase/hello2.proto b/parser/testcase/hello2.proto new file mode 100644 index 0000000..f48d46a --- /dev/null +++ b/parser/testcase/hello2.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/hello;xyz"; + +service HelloService { + rpc Hello(HelloRequest) returns(HelloResponse); +} + +message HelloRequest {} + +message HelloResponse {} + + diff --git a/parser/testcase/importpath/case1/dep1.proto b/parser/testcase/importpath/case1/dep1.proto new file mode 100644 index 0000000..4a42c49 --- /dev/null +++ b/parser/testcase/importpath/case1/dep1.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package dep; + +option go_package = "trpc.group/dep/dep1"; + +message Msg1 {} + + diff --git a/parser/testcase/importpath/case1/dep2.proto b/parser/testcase/importpath/case1/dep2.proto new file mode 100644 index 0000000..34ada76 --- /dev/null +++ b/parser/testcase/importpath/case1/dep2.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package dep; + +option go_package = "trpc.group/dep/dep1"; + +message Msg2 {} + + diff --git a/parser/testcase/importpath/case1/hello.proto b/parser/testcase/importpath/case1/hello.proto new file mode 100644 index 0000000..d6ecc09 --- /dev/null +++ b/parser/testcase/importpath/case1/hello.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/hello"; + +import "dep1.proto"; +import "dep2.proto"; + +service HelloService { + rpc Hello(HelloRequest) returns(HelloResponse); +} + +message HelloRequest {} + +message HelloResponse {} + + diff --git a/parser/testcase/importpath/case2/dep1.proto b/parser/testcase/importpath/case2/dep1.proto new file mode 100644 index 0000000..b7ba703 --- /dev/null +++ b/parser/testcase/importpath/case2/dep1.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package dep1; + +option go_package = "trpc.group/dep1/proto"; + +message Msg1 {} + + diff --git a/parser/testcase/importpath/case2/dep2.proto b/parser/testcase/importpath/case2/dep2.proto new file mode 100644 index 0000000..a6d3b93 --- /dev/null +++ b/parser/testcase/importpath/case2/dep2.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package dep2; + +option go_package = "trpc.group/dep2/proto"; + +message Msg2 {} + + diff --git a/parser/testcase/importpath/case2/hello.proto b/parser/testcase/importpath/case2/hello.proto new file mode 100644 index 0000000..c92b755 --- /dev/null +++ b/parser/testcase/importpath/case2/hello.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/hello"; + +import "dep1.proto"; +import "dep2.proto"; + +service HelloService { + rpc Hello(dep1.Msg1) returns(dep2.Msg2); +} + +message HelloRequest { + //dep1.Msg1 msg = 1; +} + +message HelloResponse { + //dep2.Msg2 msg = 2; +} + + diff --git a/parser/testcase/java/hello.proto b/parser/testcase/java/hello.proto new file mode 100644 index 0000000..e08b691 --- /dev/null +++ b/parser/testcase/java/hello.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package trpc.test.helloworld; +option java_package = "test.helloworld"; +option java_multiple_files = true; +//option java_outer_classname = "good"; +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} +// 请求参数 +message HelloRequest { + string msg = 1; +} +// 响应参数 +message HelloReply { + string msg = 1; +} + diff --git a/parser/testcase/java/test_hello.proto b/parser/testcase/java/test_hello.proto new file mode 100644 index 0000000..7124b78 --- /dev/null +++ b/parser/testcase/java/test_hello.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; +package trpc.ilive.ilive_feeds_like_svr; + +//default java package name +option java_package="com.tencent.trpcprotocol.ilive.ilivefeedslikesvr.ilivefeedslikesvr"; +option java_multiple_files = true; +option java_outer_classname = "iLiveProtocol"; +import "hello.proto"; +//default go package name +option go_package ="trpc.group/trpcprotocol/ilive/ilive_feeds_like_svr"; + +// 不建议使用 google/protobuf/any.proto +// any强依赖package type.googleapis.com/_packagename_._messagename_. +// https://developers.google.com/protocol-buffers/docs/proto3#any + +// tRPC-Go数据校验模块(**移除注释使用**) +// 介绍:http://km.oa.com/articles/view/438840 +// import "trpc/common/validate.proto"; + + + +enum ENUM_RET_CODE +{ + SUCCESS = 0; + SYSTEM_ERROR = 1000; + PARAM_ERROR = 2000; +}; + +enum ENUM_LS_LIKE_CODE +{ + DEFAULT = 0; + LIKE = 1; + UN_LIKE = 2; +}; + +// 点赞 +message FeedsLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +// 取消点赞 +message FeedsUnLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsUnLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +message QureyIsLikeReq{ + repeated string feed_id = 1; // feedid集合 + uint64 uid =2; //用户uid +} + +message FeedIdIsLikeInfo{ + string feed_Id = 1; // 文章Id + uint32 is_like = 2; // 1点赞 2未点赞 + uint64 total = 3; // 点赞总数 + uint64 forward_num = 4; //文章转发数量 +} + +message QureyIsLikeRsp{ + uint32 retcode = 1;//错误码 + string retmsg = 2; // 提示 + repeated FeedIdIsLikeInfo like_Info_list = 3; +} + +message AddArticleForwardNumReq { + string feed_Id = 1; // 文章Id + uint64 uid = 2; // 用户uid +} + +message AddArticleForwardNumRsp { + uint32 retcode = 1; //错误码 + string retmsg = 2; // 提示 + uint64 forward_num = 4; //文章转发数量 +} + + + + + +service ilive_feeds_like_svr { + // 点赞服务 + rpc FeedsLike(FeedsLikeReq) returns (FeedsLikeRsp); + // 取消点赞 + rpc FeedsUnLike(FeedsUnLikeReq) returns (FeedsUnLikeRsp); + // 查询用户是否点赞 + rpc QureyIsLike(QureyIsLikeReq) returns (QureyIsLikeRsp); + // 增加文章转发接口数量 + rpc AddArticleForwardNum(AddArticleForwardNumReq) returns (AddArticleForwardNumRsp); + + rpc ImportTest(trpc.test.helloworld.HelloRequest) returns (trpc.test.helloworld.HelloReply); +} diff --git a/parser/testcase/java/test_hello_err.proto b/parser/testcase/java/test_hello_err.proto new file mode 100644 index 0000000..7124b78 --- /dev/null +++ b/parser/testcase/java/test_hello_err.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; +package trpc.ilive.ilive_feeds_like_svr; + +//default java package name +option java_package="com.tencent.trpcprotocol.ilive.ilivefeedslikesvr.ilivefeedslikesvr"; +option java_multiple_files = true; +option java_outer_classname = "iLiveProtocol"; +import "hello.proto"; +//default go package name +option go_package ="trpc.group/trpcprotocol/ilive/ilive_feeds_like_svr"; + +// 不建议使用 google/protobuf/any.proto +// any强依赖package type.googleapis.com/_packagename_._messagename_. +// https://developers.google.com/protocol-buffers/docs/proto3#any + +// tRPC-Go数据校验模块(**移除注释使用**) +// 介绍:http://km.oa.com/articles/view/438840 +// import "trpc/common/validate.proto"; + + + +enum ENUM_RET_CODE +{ + SUCCESS = 0; + SYSTEM_ERROR = 1000; + PARAM_ERROR = 2000; +}; + +enum ENUM_LS_LIKE_CODE +{ + DEFAULT = 0; + LIKE = 1; + UN_LIKE = 2; +}; + +// 点赞 +message FeedsLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +// 取消点赞 +message FeedsUnLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsUnLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +message QureyIsLikeReq{ + repeated string feed_id = 1; // feedid集合 + uint64 uid =2; //用户uid +} + +message FeedIdIsLikeInfo{ + string feed_Id = 1; // 文章Id + uint32 is_like = 2; // 1点赞 2未点赞 + uint64 total = 3; // 点赞总数 + uint64 forward_num = 4; //文章转发数量 +} + +message QureyIsLikeRsp{ + uint32 retcode = 1;//错误码 + string retmsg = 2; // 提示 + repeated FeedIdIsLikeInfo like_Info_list = 3; +} + +message AddArticleForwardNumReq { + string feed_Id = 1; // 文章Id + uint64 uid = 2; // 用户uid +} + +message AddArticleForwardNumRsp { + uint32 retcode = 1; //错误码 + string retmsg = 2; // 提示 + uint64 forward_num = 4; //文章转发数量 +} + + + + + +service ilive_feeds_like_svr { + // 点赞服务 + rpc FeedsLike(FeedsLikeReq) returns (FeedsLikeRsp); + // 取消点赞 + rpc FeedsUnLike(FeedsUnLikeReq) returns (FeedsUnLikeRsp); + // 查询用户是否点赞 + rpc QureyIsLike(QureyIsLikeReq) returns (QureyIsLikeRsp); + // 增加文章转发接口数量 + rpc AddArticleForwardNum(AddArticleForwardNumReq) returns (AddArticleForwardNumRsp); + + rpc ImportTest(trpc.test.helloworld.HelloRequest) returns (trpc.test.helloworld.HelloReply); +} diff --git a/parser/testcase/java/test_hello_package_empty.proto b/parser/testcase/java/test_hello_package_empty.proto new file mode 100644 index 0000000..267b211 --- /dev/null +++ b/parser/testcase/java/test_hello_package_empty.proto @@ -0,0 +1,103 @@ +syntax = "proto3"; +package trpc.ilive.ilive_feeds_like_svr; +option java_multiple_files = true; +option java_outer_classname = "iLiveProtocol"; +//default go package name +option go_package ="trpc.group/trpcprotocol/ilive/ilive_feeds_like_svr"; + +// 不建议使用 google/protobuf/any.proto +// any强依赖package type.googleapis.com/_packagename_._messagename_. +// https://developers.google.com/protocol-buffers/docs/proto3#any + +// tRPC-Go数据校验模块(**移除注释使用**) +// 介绍:http://km.oa.com/articles/view/438840 +// import "trpc/common/validate.proto"; + + + +enum ENUM_RET_CODE +{ + SUCCESS = 0; + SYSTEM_ERROR = 1000; + PARAM_ERROR = 2000; +}; + +enum ENUM_LS_LIKE_CODE +{ + DEFAULT = 0; + LIKE = 1; + UN_LIKE = 2; +}; + +// 点赞 +message FeedsLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +// 取消点赞 +message FeedsUnLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsUnLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +message QureyIsLikeReq{ + repeated string feed_id = 1; // feedid集合 + uint64 uid =2; //用户uid +} + +message FeedIdIsLikeInfo{ + string feed_Id = 1; // 文章Id + uint32 is_like = 2; // 1点赞 2未点赞 + uint64 total = 3; // 点赞总数 + uint64 forward_num = 4; //文章转发数量 +} + +message QureyIsLikeRsp{ + uint32 retcode = 1;//错误码 + string retmsg = 2; // 提示 + repeated FeedIdIsLikeInfo like_Info_list = 3; +} + +message AddArticleForwardNumReq { + string feed_Id = 1; // 文章Id + uint64 uid = 2; // 用户uid +} + +message AddArticleForwardNumRsp { + uint32 retcode = 1; //错误码 + string retmsg = 2; // 提示 + uint64 forward_num = 4; //文章转发数量 +} + + + + + +service ilive_feeds_like_svr { + // 点赞服务 + rpc FeedsLike(FeedsLikeReq) returns (FeedsLikeRsp); + // 取消点赞 + rpc FeedsUnLike(FeedsUnLikeReq) returns (FeedsUnLikeRsp); + // 查询用户是否点赞 + rpc QureyIsLike(QureyIsLikeReq) returns (QureyIsLikeRsp); + // 增加文章转发接口数量 + rpc AddArticleForwardNum(AddArticleForwardNumReq) returns (AddArticleForwardNumRsp); + +} diff --git a/parser/testcase/java/test_hello_suc.proto b/parser/testcase/java/test_hello_suc.proto new file mode 100644 index 0000000..246ad60 --- /dev/null +++ b/parser/testcase/java/test_hello_suc.proto @@ -0,0 +1,106 @@ +syntax = "proto3"; +package trpc.ilive.ilive_feeds_like_svr; + +//default java package name +option java_package="com.tencent.trpcprotocol.ilive.ilivefeedslikesvr.ilivefeedslikesvr"; +option java_multiple_files = true; +option java_outer_classname = "iLiveProtocol"; +//default go package name +option go_package ="trpc.group/trpcprotocol/ilive/ilive_feeds_like_svr"; + +// 不建议使用 google/protobuf/any.proto +// any强依赖package type.googleapis.com/_packagename_._messagename_. +// https://developers.google.com/protocol-buffers/docs/proto3#any + +// tRPC-Go数据校验模块(**移除注释使用**) +// 介绍:http://km.oa.com/articles/view/438840 +// import "trpc/common/validate.proto"; + + + +enum ENUM_RET_CODE +{ + SUCCESS = 0; + SYSTEM_ERROR = 1000; + PARAM_ERROR = 2000; +}; + +enum ENUM_LS_LIKE_CODE +{ + DEFAULT = 0; + LIKE = 1; + UN_LIKE = 2; +}; + +// 点赞 +message FeedsLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +// 取消点赞 +message FeedsUnLikeReq +{ + uint64 uid = 1; + string feed_id = 2; // feedid +}; + +message FeedsUnLikeRsp +{ + uint32 total = 1; // 点赞总数 + uint32 retcode = 2;//错误码 + string retmsg = 3; // 提示 +}; + +message QureyIsLikeReq{ + repeated string feed_id = 1; // feedid集合 + uint64 uid =2; //用户uid +} + +message FeedIdIsLikeInfo{ + string feed_Id = 1; // 文章Id + uint32 is_like = 2; // 1点赞 2未点赞 + uint64 total = 3; // 点赞总数 + uint64 forward_num = 4; //文章转发数量 +} + +message QureyIsLikeRsp{ + uint32 retcode = 1;//错误码 + string retmsg = 2; // 提示 + repeated FeedIdIsLikeInfo like_Info_list = 3; +} + +message AddArticleForwardNumReq { + string feed_Id = 1; // 文章Id + uint64 uid = 2; // 用户uid +} + +message AddArticleForwardNumRsp { + uint32 retcode = 1; //错误码 + string retmsg = 2; // 提示 + uint64 forward_num = 4; //文章转发数量 +} + + + + + +service ilive_feeds_like_svr { + // 点赞服务 + rpc FeedsLike(FeedsLikeReq) returns (FeedsLikeRsp); + // 取消点赞 + rpc FeedsUnLike(FeedsUnLikeReq) returns (FeedsUnLikeRsp); + // 查询用户是否点赞 + rpc QureyIsLike(QureyIsLikeReq) returns (QureyIsLikeRsp); + // 增加文章转发接口数量 + rpc AddArticleForwardNum(AddArticleForwardNumReq) returns (AddArticleForwardNumRsp); + +} diff --git a/plugin/cpp_move.go b/plugin/cpp_move.go new file mode 100644 index 0000000..8f490f1 --- /dev/null +++ b/plugin/cpp_move.go @@ -0,0 +1,55 @@ +package plugin + +import ( + "fmt" + "os" + "path/filepath" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// CppMove is the plugin for moving proto files to proto directory in generated project. +type CppMove struct { +} + +// Name returns the plugin name. +func (p *CppMove) Name() string { + return "cpp_move" +} + +// Check only run when `--lang=cpp` +func (p *CppMove) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + return opt.Language == "cpp" && !opt.RPCOnly +} + +// Run runs moving directories action. +func (p *CppMove) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + log.Debug("execute plugin for %s in %s", opt.Language, opt.OutputDir) + pbOutDir := filepath.Join(opt.OutputDir, "proto") + // moving proto files to proto directory in generated project. + for pbFile := range fd.Pb2DepsPbs { + pbAbsPath, err := fs.LocateFile(pbFile, opt.Protodirs) + if err != nil { + fmt.Println("fs.LocateFile err: %w", err) + return nil + } + err = fs.Copy(pbAbsPath, filepath.Join(pbOutDir, pbFile)) + if err != nil { + fmt.Println("file copy err: %w", err) + return err + } + } + // add executing mode for script + scriptLs := []string{"build.sh", "clean.sh", "run_client.sh", "run_server.sh"} + for _, script := range scriptLs { + err := os.Chmod(filepath.Join(opt.OutputDir, script), 0755) + if err != nil { + fmt.Println("chmod failed err: %w", err) + return err + } + } + return nil +} diff --git a/plugin/format.go b/plugin/format.go new file mode 100644 index 0000000..7cf2985 --- /dev/null +++ b/plugin/format.go @@ -0,0 +1,35 @@ +package plugin + +import ( + "os" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/style" +) + +// Formatter is a plugin used to format generated code. +type Formatter struct { +} + +// Name return plugin's name. +func (p *Formatter) Name() string { + return "gofmt" +} + +// Check don't run if `--lang != go` +func (p *Formatter) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + if opt.Language != "go" { + return false + } + return true +} + +// Run runs gofmt action. +func (p *Formatter) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + dir, err := os.Getwd() + if err != nil { + return err + } + return style.GoFmtDir(dir) +} diff --git a/plugin/format_test.go b/plugin/format_test.go new file mode 100644 index 0000000..941c372 --- /dev/null +++ b/plugin/format_test.go @@ -0,0 +1,42 @@ +package plugin + +import ( + "errors" + "os" + "testing" + + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/style" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" +) + +func TestPlugin_Format(t *testing.T) { + u := &Formatter{} + opt := params.Option{ + Language: "go", + } + require.Equal(t, "gofmt", u.Name()) + + t.Run("go", func(t *testing.T) { + p := gomonkey.ApplyFunc(style.GoFmtDir, func(string2 string) error { + return nil + }) + p.ApplyFunc(os.Getwd, func() (string, error) { + return os.TempDir(), nil + }) + defer p.Reset() + require.True(t, u.Check(nil, &opt)) + require.Nil(t, u.Run(nil, &opt)) + }) + + t.Run("Getwd error", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (string, error) { + return "", errors.New("getwd error") + }) + defer p.Reset() + require.True(t, u.Check(nil, &opt)) + require.NotNil(t, u.Run(nil, &opt)) + }) +} diff --git a/plugin/goimports.go b/plugin/goimports.go new file mode 100644 index 0000000..e30740f --- /dev/null +++ b/plugin/goimports.go @@ -0,0 +1,55 @@ +package plugin + +import ( + "fmt" + "os/exec" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// GoImports is goimports plugin. +type GoImports struct{} + +// Name return plugin's name. +func (p *GoImports) Name() string { + return "goimports" +} + +// Check only run when `--lang=go && --goimports=true` +func (p *GoImports) Check(_ *descriptor.FileDescriptor, opt *params.Option) bool { + if opt.Language == "go" { + return true + } + return false +} + +// Run runs goimports action. +func (p *GoImports) Run(_ *descriptor.FileDescriptor, _ *params.Option) error { + goimports, err := exec.LookPath("goimports") + if err != nil { + return fmt.Errorf("goimports not found, install it first") + } + + // Under some rare circumstances, we need run goimports multiple times to + // prevent duplicate imports. + const maxGoImports = 5 + for i := 0; i < maxGoImports; i++ { + buf, err := exec.Command(goimports, "-w", ".").CombinedOutput() + if err != nil { + log.Error("run goimports -w . error: %+v,\n%s", err, string(buf)) + return err + } + buf, err = exec.Command(goimports, "-d", ".").CombinedOutput() + if err != nil { + log.Error("run goimports -d . error: %+v,\n%s", err, string(buf)) + return err + } + if len(buf) == 0 { + break + } + } + + return nil +} diff --git a/plugin/goimports_test.go b/plugin/goimports_test.go new file mode 100644 index 0000000..f39529c --- /dev/null +++ b/plugin/goimports_test.go @@ -0,0 +1,18 @@ +package plugin_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/plugin" +) + +func TestGoImports(t *testing.T) { + p := &plugin.GoImports{} + require.Equal(t, "goimports", p.Name()) + require.False(t, p.Check(&descriptor.FileDescriptor{}, ¶ms.Option{})) + require.True(t, p.Check(&descriptor.FileDescriptor{}, ¶ms.Option{Language: "go"})) + require.Nil(t, p.Run(&descriptor.FileDescriptor{}, ¶ms.Option{})) +} diff --git a/plugin/gomock.go b/plugin/gomock.go new file mode 100644 index 0000000..db486df --- /dev/null +++ b/plugin/gomock.go @@ -0,0 +1,183 @@ +package plugin + +import ( + "bufio" + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/iancoleman/strcase" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// GoMock is gomock plugin. +type GoMock struct { +} + +// Name return plugin's name. +func (p *GoMock) Name() string { + return "mockgen" +} + +// Check only run when `--lang=go || --mockgen=true` +func (p *GoMock) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + if opt.Language != "go" || !opt.Mockgen || fd == nil || len(fd.Services) == 0 { + return false + } + + // If not installed, only prompt to install, do not fail. + _, err := exec.LookPath("mockgen") + if err != nil { + log.Error("mockgen not found: %v", err) + return false + } + return true +} + +// Run runs mockgen action. +func (p *GoMock) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + if !opt.RPCOnly && opt.Mockgen { + return p.runGoGenerateAllAround(opt) + } + + wd, _ := os.Getwd() + defer os.Chdir(wd) + + os.Chdir(opt.OutputDir) + + pkgName, err := parser.GetPbPackage(fd, "go_package") + if err != nil { + return err + } + + if !opt.NoGoMod { + if err := p.ensureGoMod(pkgName); err != nil { + return err + } + } + + pkg := lang.PBValidGoPackage(pkgName) + fname := fs.BaseNameWithoutExt(fd.FilePath) + dest := fmt.Sprintf("-destination=%s_mock.go", strcase.ToSnake(fname)) + pkgv := fmt.Sprintf("-package=%s", pkg) + var selfpkgv string + if !opt.NoGoMod { + selfpkgv = fmt.Sprintf("-self_package=%s", pkgName) + } + source := fmt.Sprintf("--source=%s.trpc.go", fname) + + if err := runCmd(fmt.Sprintf("mockgen %s %s %s %s", dest, pkgv, source, selfpkgv)); err != nil { + return fmt.Errorf("go mock mockgen err: %w", err) + } + return nil +} + +// ensureGoMod ensure go mod is valid +func (p GoMock) ensureGoMod(pkgName string) error { + if err := p.checkGoMod(pkgName); err != nil { + if !os.IsNotExist(err) { + return err + } + if err := p.initGoMod(pkgName); err != nil { + return err + } + return nil + } + if err := runCmd("go mod tidy"); err != nil { + return fmt.Errorf("go mock ensure go mod err: %w", err) + } + return nil +} + +func (p *GoMock) runGoGenerateAllAround(opt *params.Option) error { + return filepath.Walk(opt.OutputDir, func(path string, info os.FileInfo, err error) error { + if !info.IsDir() { + return nil + } + matches, err := filepath.Glob(opt.OutputDir + "/*.go") + if err != nil { + return err + } + if len(matches) == 0 { + return nil + } + // Do not run go generate under stub dir. + if strings.Contains(path, "stub") { + return nil + } + + // Run "go generate". + // If wd is an actual path and path is a symbolic link, there may be problems with go generate failure, + // so path is not specified here to execute. + wd, _ := os.Getwd() + defer os.Chdir(wd) + os.Chdir(path) + log.Debug("switch to path %s from working dir %s before go generate", path, wd) + // run `go mod tidy` before `mockgen` which is specified by //go:generate + if err := runCmd("go mod tidy"); err != nil { + return fmt.Errorf("run go mod tidy inside go mock, err: %w", err) + } + if err := runCmd("go generate"); err != nil { + return fmt.Errorf("run go generate inside go mock, err: %w", err) + } + return nil + }) +} + +func (p *GoMock) initGoMod(pkg string) error { + mod := lang.TrimRight(";", pkg) + if err := runCmd("go mod init " + mod); err != nil { + return fmt.Errorf("go mock: go mod init err: %w", err) + } + + if err := runCmd("go mod tidy"); err != nil { + return fmt.Errorf("go mock: go mod tidy err: %w", err) + } + return nil +} + +func runCmd(cmd string) error { + log.Debug("run cmd: %s", cmd) + args := strings.Split(cmd, " ") + c := exec.Command(args[0], args[1:]...) + b, err := c.CombinedOutput() + if err != nil { + return fmt.Errorf("cmd exec err: %v, msg:%s", err, string(b)) + } + return nil +} + +// checkGoMod check the mod is valid +func (p *GoMock) checkGoMod(mod string) error { + f, err := os.Open("go.mod") + if err != nil { + return err + } + defer f.Close() + + const module = "module" + + br := bufio.NewScanner(f) + for br.Scan() { + s := strings.TrimSpace(br.Text()) + if !strings.HasPrefix(s, module+" ") { + continue + } + + name := s[len(module)+1:] + if name != mod { + return fmt.Errorf("当前目录已经包含go.mod (%s != %s),请通过-o指定其他输出目录", name, mod) + } + return nil + } + return errors.New("invalid go.mod") +} diff --git a/plugin/gomock_test.go b/plugin/gomock_test.go new file mode 100644 index 0000000..fd460a8 --- /dev/null +++ b/plugin/gomock_test.go @@ -0,0 +1,79 @@ +package plugin + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +func TestPlugin_Mock(t *testing.T) { + if err := setup(); err != nil { + panic(err) + } + + u := &GoMock{} + opt := params.Option{ + Language: "go", + OutputDir: filepath.Join(os.TempDir(), "trpc"), + } + os.MkdirAll(opt.OutputDir, os.ModePerm) + defer os.RemoveAll(opt.OutputDir) + + t.Run("name", func(t *testing.T) { + require.Equal(t, "mockgen", u.Name()) + }) + + // Non golang are not processed. + t.Run("lang !go", func(t *testing.T) { + u := &GoMock{} + opt := opt + opt.Language = "!go" + require.False(t, u.Check(nil, &opt)) + }) + + // It is a Go language, but if the flag --mock=false is specified, it will not be processed. + t.Run("lang go && !mockgen", func(t *testing.T) { + u := &GoMock{} + opt := opt + require.False(t, u.Check(nil, &opt)) + }) + + // If there is no service defined, it will not be processed even if it is a Go language. + t.Run("lang go && mockgen && service empty", func(t *testing.T) { + u := &GoMock{} + opt := opt + fd := &descriptor.FileDescriptor{ + Services: nil, + } + require.False(t, u.Check(fd, &opt)) + }) + + t.Run("go && mockgen && !rpconly", func(t *testing.T) { + u := &GoMock{} + opt := opt + opt.Mockgen = true + opt.RPCOnly = false + require.False(t, u.Check(nil, &opt)) + }) + + t.Run("go && mockgen && !rpconly && mockgen not installed", func(t *testing.T) { + p := gomonkey.ApplyFunc(exec.LookPath, func(file string) (string, error) { + return "", fmt.Errorf("not exist mockgen") + }) + defer p.Reset() + + u := &GoMock{} + opt := opt + opt.Mockgen = true + opt.RPCOnly = false + require.False(t, u.Check(nil, &opt)) + }) +} diff --git a/plugin/gotag.go b/plugin/gotag.go new file mode 100644 index 0000000..a22c859 --- /dev/null +++ b/plugin/gotag.go @@ -0,0 +1,312 @@ +package plugin + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "io" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/iancoleman/strcase" + "github.com/jhump/protoreflect/desc" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/descriptorpb" + trpc "trpc.group/trpc/trpc-protocol/pb/go/trpc/proto" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + tparser "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +var ( + regexpInject = regexp.MustCompile("`.+`$") + regexpTags = regexp.MustCompile(`[\w_]+:"[^"]+"`) + regexpProtobufTagName = regexp.MustCompile(`protobuf:"[\w_\-,]+name=([\w_\-]+)`) +) + +// textArea records tag text position and tag info in *.pb.go file +type textArea struct { + StartPos int + EndPos int + CurrentTag string + NewTag string +} + +// GoTag generates go tag by proto field options +type GoTag struct { +} + +// Name return plugin's name +func (p *GoTag) Name() string { + return "gotag" +} + +// Check only run when `--lang=go && --go_tag=true` +func (p *GoTag) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + if opt.Language == "go" && opt.Gotag { + return true + } + return false +} + +// Run exec go tag plugin +func (p *GoTag) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + tags := optTagsFromProto(fd.FD) + if len(tags) == 0 { + return nil + } + + outputdir := opt.OutputDir + pbfile := "" + pbname := fs.BaseNameWithoutExt(fd.FilePath) + ".pb.go" + + if opt.RPCOnly { + pbfile = filepath.Join(outputdir, pbname) + } else { + importPath, err := tparser.GetPbPackage(fd, "go_package") + if err != nil { + return err + } + pbfile = filepath.Join(outputdir, "stub", importPath, pbname) + } + + return p.replaceTags(pbfile, tags) +} + +func (p *GoTag) replaceTags(pbfile string, tags map[string]string) error { + _, err := os.Lstat(pbfile) + if err != nil { + return err + } + areas, err := tagAreasFromPBFile(pbfile, tags) + if err != nil { + return err + } + if err = injectTagsToPBFile(pbfile, areas); err != nil { + return err + } + return nil +} + +// optTagsFromProto parses field go tag option from proto file and maps it as a kv map +// map structure should be like `messageName_fieldName` +func optTagsFromProto(fd descriptor.Desc) map[string]string { + tagmap := make(map[string]string) + var scanNestedMsgFunc func(*desc.MessageDescriptor, string) + scanNestedMsgFunc = func(m *desc.MessageDescriptor, prefix string) { + for _, mm := range m.GetNestedMessageTypes() { + p := fmtgotagkey(prefix, m.GetName()) + scanNestedMsgFunc(mm, p) + } + for _, field := range m.GetFields() { + tags := getGoTag(field.GetFieldOptions()) + if tags == "" { + continue + } + key := fmtgotagkey(prefix, m.GetName(), field.GetName()) + tagmap[key] = tags + } + } + for _, msg := range fd.GetMessageTypes() { + messageDescriptor, ok := msg.(*descriptor.ProtoMessageDescriptor) + if !ok { + continue + } + md := messageDescriptor.MD + scanNestedMsgFunc(md, "") + } + return tagmap +} + +func getGoTag(opts *descriptorpb.FieldOptions) string { + if proto.HasExtension(opts, trpc.E_GoTag) { + return proto.GetExtension(opts, trpc.E_GoTag).(string) + } + return "" +} + +// fmtgotagkey generates the key for `protoTags` to join the struct name and +// field name by `_`, nested message names would be joined too +func fmtgotagkey(s ...string) string { + for k, v := range s { + if v == "" { + s = append(s[:k], s[k+1:]...) + } + } + return strcase.ToCamel(strings.Join(s, "_")) +} + +// tagAreasFromPBFile parses *.pb.go and records tag positions which need to be replaced +func tagAreasFromPBFile(fp string, newtags map[string]string) (areas []textArea, err error) { + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, fp, nil, parser.ParseComments) + if err != nil { + return + } + for _, decl := range f.Decls { + // check if is generic declaration + typeSpec := genTypeSpec(decl) + // skip if can't get type spec + if typeSpec == nil { + continue + } + // not a struct, skip + structDecl, ok := typeSpec.Type.(*ast.StructType) + if !ok { + continue + } + areas = append(areas, genAreas(structDecl, typeSpec, newtags)...) + } + return +} + +func genAreas(structDecl *ast.StructType, typeSpec *ast.TypeSpec, newtags map[string]string) []textArea { + var areas []textArea + for _, field := range structDecl.Fields.List { + if field.Tag == nil { + continue + } + fieldname := protobufTagName(field.Tag.Value) + if fieldname == "" { + continue + } + structname := typeSpec.Name.String() + // key = structName_fieldName + key := fmtgotagkey(structname, fieldname) + newtag, ok := newtags[key] + if !ok { + continue + } + currentTag := field.Tag.Value + areas = append(areas, textArea{ + StartPos: int(field.Pos()), + EndPos: int(field.End()), + CurrentTag: currentTag[1 : len(currentTag)-1], + NewTag: newtag, + }) + } + return areas +} + +func genTypeSpec(decl ast.Decl) *ast.TypeSpec { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + return nil + } + var typeSpec *ast.TypeSpec + for _, spec := range genDecl.Specs { + if ts, ok := spec.(*ast.TypeSpec); ok { + typeSpec = ts + break + } + } + return typeSpec +} + +func protobufTagName(tag string) string { + matches := regexpProtobufTagName.FindStringSubmatch(tag) + if len(matches) > 1 { + return matches[1] + } + return "" +} + +// injectTagsToPBFile replaces tags and rewrites the *.pb.go file +func injectTagsToPBFile(fp string, areas []textArea) (err error) { + f, err := os.Open(fp) + if err != nil { + return + } + contents, err := io.ReadAll(f) + if err != nil { + return + } + if err = f.Close(); err != nil { + return + } + return writeTagsToFile(fp, areas, contents, err) +} + +func writeTagsToFile(fp string, areas []textArea, contents []byte, err error) error { + // inject custom tags from tail of file first to preserve order + for i := range areas { + area := areas[len(areas)-i-1] + log.Debug("inject custom tag %q to expression %q", + area.NewTag, string(contents[area.StartPos-1:area.EndPos-1])) + contents = injectGoTag(contents, area) + } + if err = os.WriteFile(fp, contents, 0644); err != nil { + return err + } + if len(areas) > 0 { + log.Debug("file %q is injected with custom tags", fp) + } + return nil +} + +func injectGoTag(contents []byte, area textArea) (injected []byte) { + expr := make([]byte, area.EndPos-area.StartPos) + copy(expr, contents[area.StartPos-1:area.EndPos-1]) + cti := newGoTagItems(area.CurrentTag) + iti := newGoTagItems(area.NewTag) + ti := cti.override(iti) + expr = regexpInject.ReplaceAll(expr, []byte(fmt.Sprintf("`%s`", ti.format()))) + injected = append(injected, contents[:area.StartPos-1]...) + injected = append(injected, expr...) + injected = append(injected, contents[area.EndPos-1:]...) + return +} + +type goTagItem struct { + key string + value string +} + +type goTagItems []goTagItem + +func (ti goTagItems) format() string { + tags := []string{} + for _, item := range ti { + tags = append(tags, fmt.Sprintf(`%s:%s`, item.key, item.value)) + } + return strings.Join(tags, " ") +} + +func (ti goTagItems) override(nti goTagItems) goTagItems { + overridden := []goTagItem{} + for i := range ti { + var dup = -1 + for j := range nti { + if ti[i].key == nti[j].key { + dup = j + break + } + } + if dup == -1 { + overridden = append(overridden, ti[i]) + } else { + overridden = append(overridden, nti[dup]) + nti = append(nti[:dup], nti[dup+1:]...) + } + } + return append(overridden, nti...) +} + +func newGoTagItems(tag string) goTagItems { + var items goTagItems + split := regexpTags.FindAllString(tag, -1) + for _, t := range split { + sepPos := strings.Index(t, ":") + items = append(items, goTagItem{ + key: t[:sepPos], + value: t[sepPos+1:], + }) + } + return items +} diff --git a/plugin/gotag_test.go b/plugin/gotag_test.go new file mode 100644 index 0000000..3e69150 --- /dev/null +++ b/plugin/gotag_test.go @@ -0,0 +1,113 @@ +package plugin + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/paths" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +func TestPlugin_GoTag(t *testing.T) { + require.Nil(t, setup()) + u := &GoTag{} + require.Equal(t, "gotag", u.Name()) + + opt := params.Option{ + Language: "go", + Gotag: true, + OutputDir: t.TempDir(), + } + os.MkdirAll(opt.OutputDir, os.ModePerm) + defer os.RemoveAll(opt.OutputDir) + + // Don't run if not golang. + t.Run("lang !go", func(t *testing.T) { + opt := opt + opt.Language = "!go" + require.False(t, u.Check(nil, &opt)) + }) + + // Golang, but no gotag. + t.Run("go && !gotag", func(t *testing.T) { + opt := opt + opt.Gotag = false + require.False(t, u.Check(nil, &opt)) + }) + + // Run normally. + t.Run("go && gotag", func(t *testing.T) { + require.True(t, u.Check(nil, &opt)) + + // setup + opt := opt + pbf, fd, err := parseGoTagSampleProtofile() + if err != nil { + panic(err) + } + + // No corresponding pb.go file is generated for the pb file. + t.Run("lstat error", func(t *testing.T) { + require.NotNil(t, u.Run(fd, &opt)) + }) + + // Parse tags area. + t.Run("tags area", func(t *testing.T) { + opt := opt + opt.RPCOnly = true + pbd := filepath.Dir(pbf) + + wd, _ := os.Getwd() + defer os.Chdir(wd) + + os.Chdir(pbd) + + root := filepath.Clean(filepath.Join(wd, "..")) + protodirs := append([]string{ + root, + filepath.Join(root, "install"), + filepath.Join(root, "install/submodules"), + filepath.Join(root, "install/submodules/trpc"), + filepath.Join(root, "install/protos"), + filepath.Join(root, "testcase/plugins/gotag"), + }, paths.ExpandTRPCSearch(filepath.Join(root, "install"))...) + err = pb.Protoc(protodirs, pbf, "go", opt.OutputDir) + if err != nil { + panic(err) + } + + require.Nil(t, u.Run(fd, &opt)) + }) + }) +} + +func parseGoTagSampleProtofile() (string, *descriptor.FileDescriptor, error) { + wd, err := os.Getwd() + if err != nil { + return "", nil, err + } + // parse protofile + pbd := filepath.Clean(filepath.Join(wd, "../testcase/plugins/gotag")) + pbf := filepath.Join(pbd, "gotag.proto") + + dir1, err := paths.Locate(pb.ProtoTRPC) + if err != nil { + panic(err) + } + + fd, err := parser.ParseProtoFile( + "gotag.proto", + append(paths.ExpandSearch(dir1), pbd, dir1), + parser.WithLanguage("go"), + ) + if err != nil { + return "", nil, err + } + return pbf, fd, err +} diff --git a/plugin/openapi.go b/plugin/openapi.go new file mode 100644 index 0000000..c62d04b --- /dev/null +++ b/plugin/openapi.go @@ -0,0 +1,35 @@ +package plugin + +import ( + "fmt" + + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/openapi" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// OpenAPI is swagger plugin. +type OpenAPI struct { +} + +// Name return plugin's name. +func (p *OpenAPI) Name() string { + return "openapi" +} + +// Check only run when `--openapi=true` +func (p *OpenAPI) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + if opt.OpenAPIOn { + return true + } + return false +} + +// Run runs openapi action to generate openapi apidocs +func (p *OpenAPI) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + if err := openapi.GenOpenAPI(fd, opt); err != nil { + return fmt.Errorf("create open api document error: %v", err) + } + return nil +} diff --git a/plugin/openapi_test.go b/plugin/openapi_test.go new file mode 100644 index 0000000..e18f349 --- /dev/null +++ b/plugin/openapi_test.go @@ -0,0 +1,100 @@ +package plugin + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/openapi" + "trpc.group/trpc-go/trpc-cmdline/util/fs" +) + +func TestPlugin_OpenAPI(t *testing.T) { + u := &OpenAPI{} + require.Equal(t, "openapi", u.Name()) + + opt := params.Option{ + OpenAPIOn: true, + } + + // swaggeron=false, do not process. + t.Run("!openapion", func(t *testing.T) { + opt := opt + opt.OpenAPIOn = false + require.False(t, u.Check(nil, &opt)) + }) + + // openapi=true, process normally. + t.Run("openapion", func(t *testing.T) { + require.True(t, u.Check(nil, &opt)) + + pbf, fd, err := parseSampleProtofile() + if err != nil { + panic(err) + } + wd, _ := os.Getwd() + defer os.Chdir(wd) + os.Chdir(filepath.Dir(pbf)) + + opt := opt + opt.Protodirs = []string{filepath.Dir(pbf)} + opt.Protofile = pbf + opt.OpenAPIOut = filepath.Join(os.TempDir(), "xxxxxx.json") + defer os.RemoveAll(opt.OpenAPIOut) + + require.Nil(t, u.Run(fd, &opt)) + }) + + t.Run("openapion fail", func(t *testing.T) { + require.True(t, u.Check(nil, &opt)) + + p := gomonkey.ApplyFunc(openapi.GenOpenAPI, func(*descriptor.FileDescriptor, *params.Option) error { + return errors.New("gen error") + }) + defer p.Reset() + opt := opt + require.NotNil(t, u.Run(nil, &opt)) + }) +} + +func parseSampleProtofile() (string, *descriptor.FileDescriptor, error) { + wd, err := os.Getwd() + if err != nil { + return "", nil, fmt.Errorf("getwd error: %v", err) + } + // parse protofile + pbd := filepath.Clean(filepath.Join(wd, "../testcase/plugins/format")) + pbf := filepath.Join(pbd, "helloworld.proto") + outputdir := filepath.Join(os.TempDir(), "trpc") + if err := os.MkdirAll(outputdir, os.ModePerm); err != nil { + return "", nil, fmt.Errorf("mkdirall error: %v", err) + } + + fd, err := parser.ParseProtoFile( + "helloworld.proto", + []string{pbd}, + ) + if err != nil { + return "", fd, fmt.Errorf("parse proto error: %v", err) + } + + dir := filepath.Join(filepath.Dir(wd), "testcase/plugins/format") + err = fs.Copy(filepath.Join(dir, "helloworld.pb.go.txt"), filepath.Join(outputdir, "helloworld.pb.go")) + if err != nil { + return "", nil, err + } + err = fs.Copy(filepath.Join(dir, "helloworld.trpc.go.txt"), filepath.Join(outputdir, "helloworld.trpc.go")) + if err != nil { + return "", nil, err + } + + return pbf, fd, err +} diff --git a/plugin/plugin.go b/plugin/plugin.go new file mode 100644 index 0000000..74bb548 --- /dev/null +++ b/plugin/plugin.go @@ -0,0 +1,19 @@ +// Package plugin provides the ability to implement extension functionality using plugins. +package plugin + +import ( + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// Plugin represents some customized operation. +type Plugin interface { + // Name return plugin's name. + Name() string + + // Check return whether this plugin should be run. + Check(fd *descriptor.FileDescriptor, opt *params.Option) bool + + // Run runs plugin. + Run(fd *descriptor.FileDescriptor, opt *params.Option) error +} diff --git a/plugin/plugin_test.go b/plugin/plugin_test.go new file mode 100644 index 0000000..253e567 --- /dev/null +++ b/plugin/plugin_test.go @@ -0,0 +1,26 @@ +package plugin + +import ( + "os" + "testing" + + "trpc.group/trpc-go/trpc-cmdline/config" +) + +func TestMain(m *testing.M) { + if err := setup(); err != nil { + panic(err) + } + os.Exit(m.Run()) +} + +func setup() error { + if _, err := config.Init(); err != nil { + return err + } + deps, err := config.LoadDependencies() + if err != nil { + return err + } + return config.SetupDependencies(deps) +} diff --git a/plugin/plugins.go b/plugin/plugins.go new file mode 100644 index 0000000..829e3b8 --- /dev/null +++ b/plugin/plugins.go @@ -0,0 +1,28 @@ +//go:build !experimental +// +build !experimental + +package plugin + +import "trpc.group/trpc-go/trpc-cmdline/plugin/sync" + +// Plugins is the chain of public plugins. +var Plugins = []Plugin{ + &Swagger{}, // swagger apidoc + &OpenAPI{}, // openapi apidoc + &Validate{}, // protoc-gen-secv + sync.NewGit(sync.DefaultFileManager, sync.DefaultGitManager, + sync.AuthSupplier), // sync stub to git repository +} + +// PluginsExt is the language-specific plugin chain. +var PluginsExt = map[string][]Plugin{ + "go": { + &GoImports{}, // goimports, runs before mockgen, to eliminate `package import but unused` errors + &Formatter{}, // gofmt + &GoMock{}, // gomock + &GoTag{}, // custom go tag by proto field options + }, + "cpp": { + &CppMove{}, // Move the PB files to proto directory. + }, +} diff --git a/plugin/plugins_all.go b/plugin/plugins_all.go new file mode 100644 index 0000000..2bde6b1 --- /dev/null +++ b/plugin/plugins_all.go @@ -0,0 +1,25 @@ +//go:build experimental +// +build experimental + +package plugin + +import "trpc.group/trpc-go/trpc-cmdline/plugin/sync" + +// Plugins is the chain of public plugins. +var Plugins = []Plugin{ + &Swagger{}, // swagger apidoc + &OpenAPI{}, // openapi apidoc + &Validate{}, // protoc-gen-secv + sync.NewSyncGit(sync.NewDefaultFileManager(), sync.NewDefaultGitManager(), + sync.AuthSupplier), // sync stub to git repository +} + +// PluginsExt is the language-specific plugin chain. +var PluginsExt = map[string][]Plugin{ + "go": { + &GoImports{}, // goimports, runs before mockgen, to eliminate `package import but unused` errors + &Formatter{}, // gofmt + &GoMock{}, // gomock + &GoTag{}, // custom go tag by proto field options + }, +} diff --git a/plugin/swagger.go b/plugin/swagger.go new file mode 100644 index 0000000..5e25b58 --- /dev/null +++ b/plugin/swagger.go @@ -0,0 +1,26 @@ +package plugin + +import ( + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/swagger" +) + +// Swagger is swagger plugin. +type Swagger struct { +} + +// Name return plugin's name. +func (p *Swagger) Name() string { + return "swagger" +} + +// Check run only when `--swagger=true` +func (p *Swagger) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + return opt.SwaggerOn +} + +// Run run swagger plugin to generate swagger apidocs +func (p *Swagger) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + return swagger.GenSwagger(fd, opt) +} diff --git a/plugin/swagger_test.go b/plugin/swagger_test.go new file mode 100644 index 0000000..b2788c4 --- /dev/null +++ b/plugin/swagger_test.go @@ -0,0 +1,63 @@ +package plugin + +import ( + "errors" + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/swagger" +) + +func TestPlugin_Swagger(t *testing.T) { + u := &Swagger{} + require.Equal(t, "swagger", u.Name()) + + opt := params.Option{ + SwaggerOn: true, + } + + // swaggeron=false, do not process. + t.Run("!swagger", func(t *testing.T) { + opt := opt + opt.SwaggerOn = false + require.False(t, u.Check(nil, &opt)) + }) + + // swaggeron=true, process normally. + t.Run("swagger", func(t *testing.T) { + //os.chdir + pbf, fd, err := parseSampleProtofile() + if err != nil { + panic(err) + } + wd, _ := os.Getwd() + defer os.Chdir(wd) + os.Chdir(filepath.Dir(pbf)) + + opt := opt + opt.Protodirs = []string{filepath.Dir(pbf)} + opt.Protofile = pbf + opt.SwaggerOut = filepath.Join(os.TempDir(), "xxxxxx.json") + defer os.RemoveAll(opt.SwaggerOut) + + require.True(t, u.Check(nil, &opt)) + require.Nil(t, u.Run(fd, &opt)) + }) + + t.Run("swagger fail", func(t *testing.T) { + p := gomonkey.ApplyFunc(swagger.GenSwagger, func(*descriptor.FileDescriptor, *params.Option) error { + return errors.New("gen error") + }) + defer p.Reset() + + opt := opt + require.True(t, u.Check(nil, &opt)) + require.NotNil(t, u.Run(nil, &opt)) + }) +} diff --git a/plugin/sync/file.go b/plugin/sync/file.go new file mode 100644 index 0000000..cd4a89e --- /dev/null +++ b/plugin/sync/file.go @@ -0,0 +1,74 @@ +package sync + +import ( + "io" + "io/fs" + "os" + "path/filepath" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// FileManager is an interface for managing operating system files. +type FileManager interface { + RemoveAll(path string) error + WalkDir(root string, fn fs.WalkDirFunc) error + MkdirAll(path string, perm os.FileMode) error + UserHomeDir() (string, error) + + Open(name string) (*os.File, error) + Create(name string) (*os.File, error) + Close(*os.File) + Copy(dst io.Writer, src io.Reader) (written int64, err error) +} + +type defaultFileManager struct{} + +// DefaultFileManager is a default file manager constructor which creates a FileManager. +var DefaultFileManager = &defaultFileManager{} + +// RemoveAll removes path and any children it contains. +func (d *defaultFileManager) RemoveAll(path string) error { + return os.RemoveAll(path) +} + +// WalkDir walks the file tree rooted at root, calling fn for each file or +// directory in the tree, including root. +func (d *defaultFileManager) WalkDir(root string, fn fs.WalkDirFunc) error { + return filepath.WalkDir(root, fn) +} + +// MkdirAll creates a directory named path +func (d *defaultFileManager) MkdirAll(path string, perm os.FileMode) error { + return os.MkdirAll(path, perm) +} + +// UserHomeDir returns the current user's home directory. +func (d *defaultFileManager) UserHomeDir() (string, error) { + return os.UserHomeDir() +} + +// Open opens the named file for reading. +func (d *defaultFileManager) Open(name string) (*os.File, error) { + return os.Open(name) +} + +// Create creates or truncates the named file. +func (d *defaultFileManager) Create(name string) (*os.File, error) { + return os.Create(name) +} + +// Close closes the File, rendering it unusable for I/O. +func (d *defaultFileManager) Close(file *os.File) { + if err := file.Close(); err != nil { + log.Error("default file manager close error%v, file:%s", err, file.Name()) + } + return +} + +// Copy copies from src to dst until either EOF is reached +// on src or an error occurs. It returns the number of bytes +// copied and the first error encountered while copying, if any. +func (d *defaultFileManager) Copy(dst io.Writer, src io.Reader) (written int64, err error) { + return io.Copy(dst, src) +} diff --git a/plugin/sync/file_mock.go b/plugin/sync/file_mock.go new file mode 100644 index 0000000..da73555 --- /dev/null +++ b/plugin/sync/file_mock.go @@ -0,0 +1,152 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: file.go + +// Package sync is a generated GoMock package. +// mockgen -source=file.go -destination=file_mock.go -package=sync +package sync + +import ( + io "io" + fs "io/fs" + os "os" + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockFileManager is a mock of FileManager interface. +type MockFileManager struct { + ctrl *gomock.Controller + recorder *MockFileManagerMockRecorder +} + +// MockFileManagerMockRecorder is the mock recorder for MockFileManager. +type MockFileManagerMockRecorder struct { + mock *MockFileManager +} + +// NewMockFileManager creates a new mock instance. +func NewMockFileManager(ctrl *gomock.Controller) *MockFileManager { + mock := &MockFileManager{ctrl: ctrl} + mock.recorder = &MockFileManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFileManager) EXPECT() *MockFileManagerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockFileManager) Close(arg0 *os.File) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close", arg0) +} + +// Close indicates an expected call of Close. +func (mr *MockFileManagerMockRecorder) Close(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockFileManager)(nil).Close), arg0) +} + +// Copy mocks base method. +func (m *MockFileManager) Copy(dst io.Writer, src io.Reader) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Copy", dst, src) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Copy indicates an expected call of Copy. +func (mr *MockFileManagerMockRecorder) Copy(dst, src interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Copy", reflect.TypeOf((*MockFileManager)(nil).Copy), dst, src) +} + +// Create mocks base method. +func (m *MockFileManager) Create(name string) (*os.File, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Create", name) + ret0, _ := ret[0].(*os.File) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Create indicates an expected call of Create. +func (mr *MockFileManagerMockRecorder) Create(name interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockFileManager)(nil).Create), name) +} + +// MkdirAll mocks base method. +func (m *MockFileManager) MkdirAll(path string, perm os.FileMode) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MkdirAll", path, perm) + ret0, _ := ret[0].(error) + return ret0 +} + +// MkdirAll indicates an expected call of MkdirAll. +func (mr *MockFileManagerMockRecorder) MkdirAll(path, perm interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MkdirAll", reflect.TypeOf((*MockFileManager)(nil).MkdirAll), path, perm) +} + +// Open mocks base method. +func (m *MockFileManager) Open(name string) (*os.File, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Open", name) + ret0, _ := ret[0].(*os.File) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Open indicates an expected call of Open. +func (mr *MockFileManagerMockRecorder) Open(name interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockFileManager)(nil).Open), name) +} + +// RemoveAll mocks base method. +func (m *MockFileManager) RemoveAll(path string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveAll", path) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveAll indicates an expected call of RemoveAll. +func (mr *MockFileManagerMockRecorder) RemoveAll(path interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveAll", reflect.TypeOf((*MockFileManager)(nil).RemoveAll), path) +} + +// UserHomeDir mocks base method. +func (m *MockFileManager) UserHomeDir() (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UserHomeDir") + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UserHomeDir indicates an expected call of UserHomeDir. +func (mr *MockFileManagerMockRecorder) UserHomeDir() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UserHomeDir", reflect.TypeOf((*MockFileManager)(nil).UserHomeDir)) +} + +// WalkDir mocks base method. +func (m *MockFileManager) WalkDir(root string, fn fs.WalkDirFunc) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WalkDir", root, fn) + ret0, _ := ret[0].(error) + return ret0 +} + +// WalkDir indicates an expected call of WalkDir. +func (mr *MockFileManagerMockRecorder) WalkDir(root, fn interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalkDir", reflect.TypeOf((*MockFileManager)(nil).WalkDir), root, fn) +} diff --git a/plugin/sync/git.go b/plugin/sync/git.go new file mode 100644 index 0000000..ba14801 --- /dev/null +++ b/plugin/sync/git.go @@ -0,0 +1,109 @@ +package sync + +import ( + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" +) + +// GitManager is the git operations interface. +type GitManager interface { + PlainInit(path string, isBare bool) (*git.Repository, error) + PlainClone(path string, isBare bool, o *git.CloneOptions) (*git.Repository, error) + + CreateRemote(r *git.Repository, c *config.RemoteConfig) (*git.Remote, error) + Remote(r *git.Repository, name string) (*git.Remote, error) + Worktree(r *git.Repository) (*git.Worktree, error) + Push(r *git.Repository, o *git.PushOptions) error + Tags(r *git.Repository) (storer.ReferenceIter, error) + TagObject(r *git.Repository, h plumbing.Hash) (*object.Tag, error) + TagObjects(r *git.Repository) (*object.TagIter, error) + Head(r *git.Repository) (*plumbing.Reference, error) + CreateTag(r *git.Repository, name string, hash plumbing.Hash, + opts *git.CreateTagOptions) (*plumbing.Reference, error) + + AddWithOptions(w *git.Worktree, opts *git.AddOptions) error + Commit(w *git.Worktree, msg string, opts *git.CommitOptions) (plumbing.Hash, error) + + NewPublicKeysFromFile(user, pemFile, password string) (*ssh.PublicKeys, error) +} + +type defaultGitManager struct{} + +// DefaultGitManager is the constructor of the default Git manager. +var DefaultGitManager = &defaultGitManager{} + +// PlainInit create an empty git repository at the given path. +func (d *defaultGitManager) PlainInit(path string, isBare bool) (*git.Repository, error) { + return git.PlainInit(path, isBare) +} + +// PlainClone a repository into the path with the given options. +func (d *defaultGitManager) PlainClone(path string, isBare bool, o *git.CloneOptions) (*git.Repository, error) { + return git.PlainClone(path, isBare, o) +} + +// CreateRemote creates a new remote +func (d *defaultGitManager) CreateRemote(r *git.Repository, c *config.RemoteConfig) (*git.Remote, error) { + return r.CreateRemote(c) +} + +// Remote return a remote if exists +func (d *defaultGitManager) Remote(r *git.Repository, name string) (*git.Remote, error) { + return r.Remote(name) +} + +// Worktree returns a worktree based on the given fs, if nil the default worktree will be used. +func (d *defaultGitManager) Worktree(r *git.Repository) (*git.Worktree, error) { + return r.Worktree() +} + +// Push performs a push to the remote. +func (d *defaultGitManager) Push(r *git.Repository, o *git.PushOptions) error { + return r.Push(o) +} + +// Tags returns all the References from Tags. +func (d *defaultGitManager) Tags(r *git.Repository) (storer.ReferenceIter, error) { + return r.Tags() +} + +// TagObject returns a Tag with the given hash. +func (d *defaultGitManager) TagObject(r *git.Repository, h plumbing.Hash) (*object.Tag, error) { + return r.TagObject(h) +} + +// TagObjects returns a unsorted TagIter that can step through all of the annotated tags in the repository. +func (d *defaultGitManager) TagObjects(r *git.Repository) (*object.TagIter, error) { + return r.TagObjects() +} + +// Head returns the reference where HEAD is pointing to. +func (d *defaultGitManager) Head(r *git.Repository) (*plumbing.Reference, error) { + return r.Head() +} + +// CreateTag create a tag. +func (d *defaultGitManager) CreateTag(r *git.Repository, name string, hash plumbing.Hash, + opts *git.CreateTagOptions) (*plumbing.Reference, error) { + return r.CreateTag(name, hash, opts) +} + +// AddWithOptions add with options for worktree. +func (d *defaultGitManager) AddWithOptions(w *git.Worktree, opts *git.AddOptions) error { + return w.AddWithOptions(opts) +} + +// Commit stores the current contents of the index in a new commit along with +// a log message from the user describing the changes. +func (d *defaultGitManager) Commit(w *git.Worktree, msg string, opts *git.CommitOptions) (plumbing.Hash, error) { + return w.Commit(msg, opts) +} + +// NewPublicKeysFromFile returns a PublicKeys from a file containing a PEM encoded private key. +func (d *defaultGitManager) NewPublicKeysFromFile(user, pemFile, password string) (*ssh.PublicKeys, error) { + return ssh.NewPublicKeysFromFile(user, pemFile, password) +} diff --git a/plugin/sync/git_mock.go b/plugin/sync/git_mock.go new file mode 100644 index 0000000..a9ad15b --- /dev/null +++ b/plugin/sync/git_mock.go @@ -0,0 +1,249 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: git.go + +// Package sync is a generated GoMock package. +// mockgen -source=git.go -destination=git_mock.go -package=sync +package sync + +import ( + reflect "reflect" + + git "github.com/go-git/go-git/v5" + config "github.com/go-git/go-git/v5/config" + plumbing "github.com/go-git/go-git/v5/plumbing" + object "github.com/go-git/go-git/v5/plumbing/object" + storer "github.com/go-git/go-git/v5/plumbing/storer" + ssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" + gomock "github.com/golang/mock/gomock" +) + +// MockGitManager is a mock of GitManager interface. +type MockGitManager struct { + ctrl *gomock.Controller + recorder *MockGitManagerMockRecorder +} + +// MockGitManagerMockRecorder is the mock recorder for MockGitManager. +type MockGitManagerMockRecorder struct { + mock *MockGitManager +} + +// NewMockGitManager creates a new mock instance. +func NewMockGitManager(ctrl *gomock.Controller) *MockGitManager { + mock := &MockGitManager{ctrl: ctrl} + mock.recorder = &MockGitManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGitManager) EXPECT() *MockGitManagerMockRecorder { + return m.recorder +} + +// AddWithOptions mocks base method. +func (m *MockGitManager) AddWithOptions(w *git.Worktree, opts *git.AddOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddWithOptions", w, opts) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddWithOptions indicates an expected call of AddWithOptions. +func (mr *MockGitManagerMockRecorder) AddWithOptions(w, opts interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddWithOptions", reflect.TypeOf((*MockGitManager)(nil).AddWithOptions), w, opts) +} + +// Commit mocks base method. +func (m *MockGitManager) Commit(w *git.Worktree, msg string, opts *git.CommitOptions) (plumbing.Hash, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit", w, msg, opts) + ret0, _ := ret[0].(plumbing.Hash) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Commit indicates an expected call of Commit. +func (mr *MockGitManagerMockRecorder) Commit(w, msg, opts interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockGitManager)(nil).Commit), w, msg, opts) +} + +// CreateRemote mocks base method. +func (m *MockGitManager) CreateRemote(r *git.Repository, c *config.RemoteConfig) (*git.Remote, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateRemote", r, c) + ret0, _ := ret[0].(*git.Remote) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateRemote indicates an expected call of CreateRemote. +func (mr *MockGitManagerMockRecorder) CreateRemote(r, c interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateRemote", reflect.TypeOf((*MockGitManager)(nil).CreateRemote), r, c) +} + +// CreateTag mocks base method. +func (m *MockGitManager) CreateTag(r *git.Repository, name string, hash plumbing.Hash, opts *git.CreateTagOptions) (*plumbing.Reference, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateTag", r, name, hash, opts) + ret0, _ := ret[0].(*plumbing.Reference) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateTag indicates an expected call of CreateTag. +func (mr *MockGitManagerMockRecorder) CreateTag(r, name, hash, opts interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTag", reflect.TypeOf((*MockGitManager)(nil).CreateTag), r, name, hash, opts) +} + +// Head mocks base method. +func (m *MockGitManager) Head(r *git.Repository) (*plumbing.Reference, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Head", r) + ret0, _ := ret[0].(*plumbing.Reference) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Head indicates an expected call of Head. +func (mr *MockGitManagerMockRecorder) Head(r interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Head", reflect.TypeOf((*MockGitManager)(nil).Head), r) +} + +// NewPublicKeysFromFile mocks base method. +func (m *MockGitManager) NewPublicKeysFromFile(user, pemFile, password string) (*ssh.PublicKeys, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewPublicKeysFromFile", user, pemFile, password) + ret0, _ := ret[0].(*ssh.PublicKeys) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NewPublicKeysFromFile indicates an expected call of NewPublicKeysFromFile. +func (mr *MockGitManagerMockRecorder) NewPublicKeysFromFile(user, pemFile, password interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewPublicKeysFromFile", reflect.TypeOf((*MockGitManager)(nil).NewPublicKeysFromFile), user, pemFile, password) +} + +// PlainClone mocks base method. +func (m *MockGitManager) PlainClone(path string, isBare bool, o *git.CloneOptions) (*git.Repository, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PlainClone", path, isBare, o) + ret0, _ := ret[0].(*git.Repository) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PlainClone indicates an expected call of PlainClone. +func (mr *MockGitManagerMockRecorder) PlainClone(path, isBare, o interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PlainClone", reflect.TypeOf((*MockGitManager)(nil).PlainClone), path, isBare, o) +} + +// PlainInit mocks base method. +func (m *MockGitManager) PlainInit(path string, isBare bool) (*git.Repository, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PlainInit", path, isBare) + ret0, _ := ret[0].(*git.Repository) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PlainInit indicates an expected call of PlainInit. +func (mr *MockGitManagerMockRecorder) PlainInit(path, isBare interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PlainInit", reflect.TypeOf((*MockGitManager)(nil).PlainInit), path, isBare) +} + +// Push mocks base method. +func (m *MockGitManager) Push(r *git.Repository, o *git.PushOptions) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Push", r, o) + ret0, _ := ret[0].(error) + return ret0 +} + +// Push indicates an expected call of Push. +func (mr *MockGitManagerMockRecorder) Push(r, o interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Push", reflect.TypeOf((*MockGitManager)(nil).Push), r, o) +} + +// Remote mocks base method. +func (m *MockGitManager) Remote(r *git.Repository, name string) (*git.Remote, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Remote", r, name) + ret0, _ := ret[0].(*git.Remote) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Remote indicates an expected call of Remote. +func (mr *MockGitManagerMockRecorder) Remote(r, name interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Remote", reflect.TypeOf((*MockGitManager)(nil).Remote), r, name) +} + +// TagObject mocks base method. +func (m *MockGitManager) TagObject(r *git.Repository, h plumbing.Hash) (*object.Tag, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TagObject", r, h) + ret0, _ := ret[0].(*object.Tag) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TagObject indicates an expected call of TagObject. +func (mr *MockGitManagerMockRecorder) TagObject(r, h interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TagObject", reflect.TypeOf((*MockGitManager)(nil).TagObject), r, h) +} + +// TagObjects mocks base method. +func (m *MockGitManager) TagObjects(r *git.Repository) (*object.TagIter, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TagObjects", r) + ret0, _ := ret[0].(*object.TagIter) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TagObjects indicates an expected call of TagObjects. +func (mr *MockGitManagerMockRecorder) TagObjects(r interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TagObjects", reflect.TypeOf((*MockGitManager)(nil).TagObjects), r) +} + +// Tags mocks base method. +func (m *MockGitManager) Tags(r *git.Repository) (storer.ReferenceIter, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Tags", r) + ret0, _ := ret[0].(storer.ReferenceIter) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Tags indicates an expected call of Tags. +func (mr *MockGitManagerMockRecorder) Tags(r interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tags", reflect.TypeOf((*MockGitManager)(nil).Tags), r) +} + +// Worktree mocks base method. +func (m *MockGitManager) Worktree(r *git.Repository) (*git.Worktree, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Worktree", r) + ret0, _ := ret[0].(*git.Worktree) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Worktree indicates an expected call of Worktree. +func (mr *MockGitManagerMockRecorder) Worktree(r interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Worktree", reflect.TypeOf((*MockGitManager)(nil).Worktree), r) +} diff --git a/plugin/sync/sync_git.go b/plugin/sync/sync_git.go new file mode 100644 index 0000000..55c12eb --- /dev/null +++ b/plugin/sync/sync_git.go @@ -0,0 +1,407 @@ +// Package sync uses the post-plugin extension point to push the generated PB stub code to a remote git repository. +package sync + +import ( + "fmt" + "io" + "io/fs" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/plumbing/transport" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +const ( + sshGitURLPrefix = "git@" + sshGitDomainSep = ":" + gitURLSuffix = ".git" + trpcGeneratedStubName = "stub" + gitURLPathSep = "/" + defaultGitTag = "v1.1.1" + gitTagNameSep = "." + defaultGitTagLen = 3 +) + +// Git provides git synchronization capabilities. +type Git struct { + auth transport.AuthMethod + newErr error + + fileManager FileManager + gitManager GitManager +} + +// NewGit is a constructor for syncing stubs to a git repository. +// fileManager: File management interface +// gitManager: Git management interface +// supplier: Injection of Git access authorization methods +func NewGit( + fileManager FileManager, + gitManager GitManager, + supplier func(FileManager, GitManager) (transport.AuthMethod, error), +) *Git { + sg := &Git{ + fileManager: fileManager, + gitManager: gitManager, + } + sg.auth, sg.newErr = supplier(fileManager, gitManager) + return sg +} + +// AuthSupplier provides access to a git remote repository via SSH by default. +func AuthSupplier(fileManager FileManager, gitManager GitManager) (transport.AuthMethod, error) { + homePath, err := fileManager.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("os user home dir err: %w", err) + } + rsaFilePath := filepath.Join(homePath, ".ssh/id_rsa") + publicKeys, err := gitManager.NewPublicKeysFromFile("git", rsaFilePath, "") + if err != nil { + return nil, fmt.Errorf("git ssh new public keys from file error: %w, file location %s", err, rsaFilePath) + } + return publicKeys, nil +} + +// Name of the remote git repository sync plugin. +func (s *Git) Name() string { + return "sync_git" +} + +// Check checks whether to perform remote synchronization. +func (s *Git) Check(_ *descriptor.FileDescriptor, opt *params.Option) bool { + return opt.Sync +} + +// Run syncs the remote Git repository. +func (s *Git) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + if s.newErr != nil { + return s.newErr + } + gitDir, r, err := s.cloneOrInitGitDir(fd.GoPackage, opt) + if err != nil { + return err + } + defer func() { + if err := s.fileManager.RemoveAll(gitDir); err != nil { + log.Error("sync git plugin run file manager remove dir:%s error:%v", gitDir, err) + } + }() + outStubDir := filepath.Join(opt.OutputDir, trpcGeneratedStubName) + if err := s.copyStubToGitDir(outStubDir, gitDir, s.getRemoteGitURLBase(r)); err != nil { + return err + } + return s.commitAndPushGitDir(r, opt) +} + +func (s *Git) cloneOrInitGitDir(goPackage string, opt *params.Option) (string, *git.Repository, error) { + urlPrefix, paths, err := parseGitURLComponent(goPackage, opt) + if err != nil { + return "", nil, err + } + tempGitDir := filepath.Join(opt.OutputDir, "stub_temp") + if err := s.fileManager.RemoveAll(tempGitDir); err != nil { + return "", nil, err + } + r, err := s.cloneOrInitGitRepo(urlPrefix+sshGitDomainSep, tempGitDir, paths) + if err != nil { + return "", nil, err + } + return tempGitDir, r, nil +} + +// cloneOrInitGitRepo recursively constructs git url using path. +// For example, the git address of trpc.group/veteranchen/test/helloworld may be: +// trpc.group/veteranchen.git +// trpc.group/veteranchen/test.git +// trpc.group/veteranchen/test/helloworld.git +func (s *Git) cloneOrInitGitRepo(urlPrefix string, tempDir string, paths []string) (*git.Repository, error) { + if len(paths) == 0 { + return nil, fmt.Errorf("not found clone git repository, please create git repository") + } + gitURL := urlPrefix + strings.Join(paths, gitURLPathSep) + gitURLSuffix + r, err := s.gitManager.PlainClone(tempDir, false, &git.CloneOptions{ + Auth: s.auth, + URL: gitURL, + RecurseSubmodules: git.DefaultSubmoduleRecursionDepth, + }) + if err == transport.ErrEmptyRemoteRepository { + return s.initGitRepo(tempDir, gitURL) + } + if err == nil && r != nil { + return r, nil + } + return s.cloneOrInitGitRepo(urlPrefix, tempDir, paths[:len(paths)-1]) +} + +func (s *Git) initGitRepo(tempDir, gitURL string) (*git.Repository, error) { + r, err := s.gitManager.PlainInit(tempDir, false) + if err != nil { + return nil, fmt.Errorf("git init error: %w url: %s", err, tempDir) + } + if _, err := s.gitManager.CreateRemote(r, &config.RemoteConfig{ + Name: "origin", + URLs: []string{gitURL}, + }); err != nil { + return nil, fmt.Errorf("git create remote err: %w gitUrl: %v", err, gitURL) + } + return r, nil +} + +// parseGitURLComponent parses the given git URL and returns the prefix, as well as the array of path components. +func parseGitURLComponent(goPackage string, opt *params.Option) (string, []string, error) { + gitURL := opt.Remote + if gitURL == "" { + gitURL = sshGitURLPrefix + strings.Replace(goPackage, gitURLPathSep, sshGitDomainSep, 1) + gitURLSuffix + } + if !strings.Contains(gitURL, sshGitDomainSep) { + return "", nil, fmt.Errorf("ssh git url pattern is invalid %s", gitURL) + } + if !strings.HasPrefix(gitURL, sshGitURLPrefix) { + return "", nil, fmt.Errorf("ssh git url pattern is invalid %s", gitURL) + } + if !strings.HasSuffix(gitURL, gitURLSuffix) { + return "", nil, fmt.Errorf("ssh git url pattern is invalid %s", gitURL) + } + urlComps := strings.Split(gitURL, sshGitDomainSep) + return urlComps[0], strings.Split(strings.TrimSuffix(urlComps[1], gitURLSuffix), gitURLPathSep), nil +} + +func (s *Git) commitAndPushGitDir(r *git.Repository, opt *params.Option) error { + w, err := s.gitManager.Worktree(r) + if err != nil { + return fmt.Errorf("git repository work tree err: %w", err) + } + if err := s.gitManager.AddWithOptions(w, &git.AddOptions{ + All: true, + }); err != nil { + return fmt.Errorf("git add err: %w", err) + } + if _, err := s.gitManager.Commit(w, "the generated stub pb is pushed to git repository", + &git.CommitOptions{All: true}); err != nil { + return fmt.Errorf("git commit err: %w", err) + } + // Tag the target repo. + if opt.NewTag { + if err = s.setTag(r, opt); err != nil { + return err + } + } + if err := s.gitManager.Push(r, &git.PushOptions{ + RefSpecs: []config.RefSpec{"refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"}, + Auth: s.auth, + }); err != nil { + return fmt.Errorf("git push err: %w", err) + } + return nil +} + +func (s *Git) copyStubToGitDir(localStubDir, localGitDir, gitURLBase string) error { + pbFiles, err := s.collectPBFileFullPaths(localStubDir) + if err != nil { + return err + } + pbDir := filepath.Dir(pbFiles[0]) + pbDirBase := filepath.Base(pbDir) // Get the last segment of the directory. + defaultSuffix := parseDefaultPathSuffix(pbDir, gitURLBase) + gitDstPath, err := s.extractGitDstDirFullPath(pbDirBase, localGitDir, defaultSuffix) + if err != nil { + return err + } + for _, f := range pbFiles { + if err := s.copyPBFileToGitDir(f, gitDstPath); err != nil { + return fmt.Errorf( + "copy stub to git local dir error: %w, localStubDir: %s, localGitDir: %s", + err, localStubDir, localGitDir) + } + } + return nil +} + +func parseDefaultPathSuffix(pbDir, gitURLBase string) string { + dirs := strings.Split(pbDir, string(os.PathSeparator)) + idx := -1 + lastIdx := len(dirs) - 1 + for i := lastIdx; i >= 0; i-- { + if dirs[i] == gitURLBase { + idx = i + 1 + break + } + } + if idx == -1 { + return filepath.Base(pbDir) + } + return filepath.Join(dirs[idx:]...) +} + +func (s *Git) collectPBFileFullPaths(outDir string) ([]string, error) { + pbFiles := make([]string, 0, 8) + if err := s.fileManager.WalkDir(outDir, func(path string, d fs.DirEntry, err error) error { + if d == nil || d.IsDir() { + return nil + } + pbFiles = append(pbFiles, path) + return nil + }); err != nil { + return nil, err + } + if len(pbFiles) == 0 { + return nil, fmt.Errorf("generated stub file is empty") + } + if !isSameDir(pbFiles) { + return nil, fmt.Errorf("generated stub file not is same dir") + } + return pbFiles, nil +} + +func (s *Git) extractGitDstDirFullPath(pbDirBase, localGitDir, defaultSuffix string) (string, error) { + dstGitDir := "" + if err := s.fileManager.WalkDir(localGitDir, func(path string, d fs.DirEntry, err error) error { + if d != nil && d.IsDir() && d.Name() == pbDirBase { + dstGitDir = path + } + return nil + }); err != nil { + return "", err + } + if dstGitDir == "" { + dstGitDir = filepath.Join(localGitDir, defaultSuffix) + if err := s.fileManager.MkdirAll(dstGitDir, os.ModePerm); err != nil { + return "", fmt.Errorf("mk git local destination dir %s error: %w", dstGitDir, err) + } + } + return dstGitDir, nil +} + +func (s *Git) copyPBFileToGitDir(pbFile string, gitDir string) error { + dstFile := filepath.Join(gitDir, filepath.Base(pbFile)) + source, err := s.fileManager.Open(pbFile) + if err != nil { + return err + } + defer s.fileManager.Close(source) + if err := s.fileManager.RemoveAll(dstFile); err != nil { + return err + } + destination, err := s.fileManager.Create(dstFile) + if err != nil { + return err + } + defer s.fileManager.Close(destination) + if _, err := s.fileManager.Copy(destination, source); err != nil { + return err + } + return nil +} + +func isSameDir(files []string) bool { + dir := filepath.Dir(files[0]) + for i := 1; i < len(files); i++ { + if dir != filepath.Dir(files[i]) { + return false + } + } + return true +} + +func (s *Git) setTag(r *git.Repository, opt *params.Option) error { + tag := opt.Tag + if tag == "" { + var err error + tag, err = s.evalTagName(r) + if err != nil { + return err + } + } else { + if err := s.tagExists(r, tag); err != nil { + return err + } + } + h, err := s.gitManager.Head(r) + if err != nil { + return err + } + if _, err := s.gitManager.CreateTag(r, tag, h.Hash(), &git.CreateTagOptions{Message: tag}); err != nil { + return err + } + return nil +} + +func (s *Git) tagExists(r *git.Repository, tag string) error { + tagFoundErr := "tag name is existed" + tags, err := s.gitManager.TagObjects(r) + if err != nil { + return err + } + return tags.ForEach(func(t *object.Tag) error { + if t.Name == tag { + return fmt.Errorf(tagFoundErr) + } + return nil + }) +} + +func (s *Git) evalTagName(r *git.Repository) (string, error) { + tags, err := s.gitManager.Tags(r) + if err != nil { + return "", fmt.Errorf("when eval tag name, git get tags err: %w", err) + } + lastTag, err := tags.Next() + for curTag := lastTag; err != io.EOF; curTag, err = tags.Next() { + lastTag = curTag + } + if lastTag == nil { + return defaultGitTag, nil + } + tagObj, err := s.gitManager.TagObject(r, lastTag.Hash()) + if err != nil { + return "", fmt.Errorf("when eval tag name, git get tag object err: %w", err) + } + return genNewTagName(tagObj.Name), nil +} + +// genNewTagName generates a new tag name based on the latest tag name. +// If it follows the v1.1.1 format, increment the last version. If it reaches 99, carry over the middle version. +func genNewTagName(lastTagName string) string { + tags := strings.Split(lastTagName, gitTagNameSep) + if len(tags) != defaultGitTagLen { + return defaultGitTag + } + v3, err := strconv.Atoi(tags[2]) + if err != nil { + return defaultGitTag + } + v3++ + if v3 < 100 { + tags[2] = strconv.Itoa(v3) + return strings.Join(tags, gitTagNameSep) + } + v2, err := strconv.Atoi(tags[1]) + if err != nil { + return defaultGitTag + } + v2++ + tags[1], tags[2] = strconv.Itoa(v2), "1" + return strings.Join(tags, gitTagNameSep) +} + +func (s *Git) getRemoteGitURLBase(repo *git.Repository) string { + r, err := s.gitManager.Remote(repo, "origin") + if err != nil { + return "" + } + url := r.Config().URLs[0] + index := strings.LastIndex(url, gitURLPathSep) + if index == -1 { + return "" + } + return strings.TrimSuffix(url[index+1:], gitURLSuffix) +} diff --git a/plugin/sync/sync_git_test.go b/plugin/sync/sync_git_test.go new file mode 100644 index 0000000..2570f28 --- /dev/null +++ b/plugin/sync/sync_git_test.go @@ -0,0 +1,203 @@ +package sync + +import ( + "fmt" + "io/fs" + "os" + "strings" + "testing" + "testing/fstest" + "time" + + "github.com/go-git/go-billy/v5/memfs" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/plumbing/storer" + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "github.com/go-git/go-git/v5/storage/memory" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// A mapFileInfo implements fs.FileInfo and fs.DirEntry for a given map file. +type mapFileInfo struct { + name string + f *fstest.MapFile +} + +func (i *mapFileInfo) Name() string { return i.name } +func (i *mapFileInfo) Size() int64 { return int64(len(i.f.Data)) } +func (i *mapFileInfo) Mode() fs.FileMode { return i.f.Mode } +func (i *mapFileInfo) Type() fs.FileMode { return i.f.Mode.Type() } +func (i *mapFileInfo) ModTime() time.Time { return i.f.ModTime } +func (i *mapFileInfo) IsDir() bool { return i.f.Mode&fs.ModeDir != 0 } +func (i *mapFileInfo) Sys() interface{} { return i.f.Sys } +func (i *mapFileInfo) Info() (fs.FileInfo, error) { return i, nil } + +func newMapFileInfos() map[string]*mapFileInfo { + res := make(map[string]*mapFileInfo, 3) + res["/GolandProjects/issue-shoot-owner/test/stub/trpc.group/cpme_contentcreate/test/helloworld"] = + &mapFileInfo{ + name: "helloworld", + f: &fstest.MapFile{ + Mode: fs.ModeDir, + ModTime: time.Time{}, + }, + } + res["/GolandProjects/issue-shoot-owner/test/stub/trpc.group/cpme_contentcreate/test/helloworld/hello.pb.go"] = + &mapFileInfo{ + name: "hello.pb.go", + f: &fstest.MapFile{ + Mode: fs.ModePerm, + ModTime: time.Time{}, + }, + } + res["/GolandProjects/issue-shoot-owner/test/stub/trpc.group/cpme_contentcreate"+ + "/test/helloworld/hello.trpc.go"] = &mapFileInfo{ + name: "hello.trpc.go", + f: &fstest.MapFile{ + Mode: fs.ModePerm, + ModTime: time.Time{}, + }, + } + return res +} + +func walkDirMockFunc(_ string, fn fs.WalkDirFunc) error { + for path, de := range newMapFileInfos() { + if err := fn(path, de, nil); err != nil { + return err + } + } + return nil +} + +func executeGoMock(t *testing.T) (*gomock.Controller, FileManager, GitManager) { + ctrl := gomock.NewController(t) + fm := NewMockFileManager(ctrl) + fm.EXPECT().RemoveAll(gomock.Any()).Return(nil).AnyTimes() + fm.EXPECT().WalkDir(gomock.Any(), gomock.Any()).DoAndReturn(walkDirMockFunc).AnyTimes() + fm.EXPECT().MkdirAll(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + fm.EXPECT().Open(gomock.Any()).Return(&os.File{}, nil).AnyTimes() + fm.EXPECT().Create(gomock.Any()).Return(&os.File{}, nil).AnyTimes() + fm.EXPECT().Close(gomock.Any()).AnyTimes() + fm.EXPECT().Copy(gomock.Any(), gomock.Any()).Return(int64(1024), nil).AnyTimes() + fm.EXPECT().UserHomeDir().Return("/Users/veteranchen", nil).AnyTimes() + + gm := NewMockGitManager(ctrl) + repo, _ := git.Init(memory.NewStorage(), memfs.New()) + remote := git.NewRemote(nil, &config.RemoteConfig{ + URLs: []string{"git@trpc.group:veteranchen/test.git"}, + }) + w, _ := repo.Worktree() + slice := []*plumbing.Reference{ + plumbing.NewReferenceFromStrings("v1.2.99", "v1.2.99"), + plumbing.NewReferenceFromStrings("v1.1.2", "v1.1.2"), + plumbing.NewReferenceFromStrings("v1.1.99", "v1.1.99"), + } + iter := storer.NewReferenceSliceIter(slice) + tag := &object.Tag{ + Name: "v1.2.99", + } + tagIter, _ := repo.TagObjects() + ref := plumbing.NewReferenceFromStrings("12345", "67890") + gm.EXPECT().PlainInit(gomock.Any(), gomock.Any()).Return(repo, nil).AnyTimes() + gm.EXPECT().PlainClone(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( + func(path string, isBare bool, o *git.CloneOptions) (*git.Repository, error) { + if strings.Contains(path, "initGitRepo") { + return nil, transport.ErrEmptyRemoteRepository + } + if strings.Contains(path, "cloneGitRepoFailure") { + return nil, transport.ErrInvalidAuthMethod + } + return repo, nil + }).AnyTimes() + gm.EXPECT().CreateRemote(gomock.Any(), gomock.Any()).Return(remote, nil).AnyTimes() + gm.EXPECT().Remote(gomock.Any(), gomock.Any()).Return(remote, nil).AnyTimes() + gm.EXPECT().Worktree(gomock.Any()).Return(w, nil).AnyTimes() + gm.EXPECT().Push(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + gm.EXPECT().Tags(gomock.Any()).DoAndReturn(func(r *git.Repository) (storer.ReferenceIter, error) { + return iter, nil + }).AnyTimes() + gm.EXPECT().TagObject(gomock.Any(), gomock.Any()).Return(tag, nil).AnyTimes() + gm.EXPECT().TagObjects(gomock.Any()).Return(tagIter, nil).AnyTimes() + gm.EXPECT().Head(gomock.Any()).Return(ref, nil).AnyTimes() + gm.EXPECT().CreateTag(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(ref, nil).AnyTimes() + gm.EXPECT().AddWithOptions(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + gm.EXPECT().Commit(gomock.Any(), gomock.Any(), gomock.Any()).Return(plumbing.NewHash("12345678"), nil).AnyTimes() + publicKeys, _ := ssh.NewPublicKeys("git", []byte("1234"), "12345") + gm.EXPECT().NewPublicKeysFromFile(gomock.Any(), gomock.Any(), gomock.Any()).Return(publicKeys, nil).AnyTimes() + return ctrl, fm, gm +} + +func buildGitAndOptions(t *testing.T) (*Git, *params.Option, *descriptor.FileDescriptor, *gomock.Controller) { + ctrl, fm, gm := executeGoMock(t) + return NewGit(fm, gm, AuthSupplier), ¶ms.Option{ + Sync: true, + Remote: "", + NewTag: true, + Tag: "", + OutputDir: "/GolandProjects/issue-shoot-owner/test/stub/trpc.group/cpme_contentcreate/test/helloworld", + }, &descriptor.FileDescriptor{ + GoPackage: "trpc.group/veteranchen/test/helloworld", + }, ctrl +} + +func TestSyncGit_Run(t *testing.T) { + sGit, opts, fd, ctrl := buildGitAndOptions(t) + defer ctrl.Finish() + require.Equal(t, "sync_git", sGit.Name()) + require.True(t, sGit.Check(fd, opts)) + err := sGit.Run(fd, opts) + require.Nil(t, err) + + opts.Tag = "v2.0.99" + err = sGit.Run(fd, opts) + require.Nil(t, err) +} + +func TestSyncGit_cloneGitDir(t *testing.T) { + sGit, opts, _, ctrl := buildGitAndOptions(t) + defer ctrl.Finish() + dir, r, err := sGit.cloneOrInitGitDir("trpc.group/veteranchen/test/helloworld", opts) + require.Nil(t, err) + require.NotNil(t, r) + require.NotEmpty(t, dir) + + opts.Remote = "https://trpc.group/veteranchen/test.git" + dir, r, err = sGit.cloneOrInitGitDir("trpc.group/veteranchen/test/helloworld", opts) + fmt.Println(err) + require.NotNil(t, err) + + opts.Remote = "git@trpc.group/veteranchen/test.git" + dir, r, err = sGit.cloneOrInitGitDir("trpc.group/veteranchen/test/helloworld", opts) + fmt.Println(err) + require.NotNil(t, err) + + opts.Remote = "git@trpc.group:veteranchen/test" + dir, r, err = sGit.cloneOrInitGitDir("trpc.group/veteranchen/test/helloworld", opts) + fmt.Println(err) + require.NotNil(t, err) +} + +func TestSyncGit_Run_initGitRepo(t *testing.T) { + sGit, opts, fd, ctrl := buildGitAndOptions(t) + defer ctrl.Finish() + opts.OutputDir = "/GolandProjects/issue-shoot-owner/test/stub/trpc.group/initGitRepo/test/helloworld" + err := sGit.Run(fd, opts) + require.Nil(t, err) +} + +func TestSyncGit_Run_cloneGitRepoFailure(t *testing.T) { + sGit, opts, fd, ctrl := buildGitAndOptions(t) + defer ctrl.Finish() + opts.OutputDir = "/GolandProjects/issue-shoot-owner/test/stub/trpc.group/cloneGitRepoFailure/test/helloworld" + err := sGit.Run(fd, opts) + require.NotNil(t, err) +} diff --git a/plugin/validate.go b/plugin/validate.go new file mode 100644 index 0000000..e56e2fa --- /dev/null +++ b/plugin/validate.go @@ -0,0 +1,71 @@ +package plugin + +import ( + "os" + "path/filepath" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +// Validate is validate plugin. +type Validate struct { +} + +// Name return plugin's name. +func (p *Validate) Name() string { + return "validate" +} + +var supported = map[string]bool{ + "go": true, +} + +// Check only run when language is supported. +func (p *Validate) Check(fd *descriptor.FileDescriptor, opt *params.Option) bool { + if _, ok := supported[opt.Language]; !ok { + return false + } + + // Check if validation feature is enabled in pb and generate go files. + return parser.CheckSECVEnabled(fd) +} + +// Run runs protoc-gen-validate to generate validate.pb.go +// +// Only supports a few programming languages. See: https://trpc.group/devsec/protoc-gen-secv +func (p *Validate) Run(fd *descriptor.FileDescriptor, opt *params.Option) error { + + var ( + pbOutDir string + err error + ) + + outputdir := opt.OutputDir + + if !opt.RPCOnly { + stubDir := filepath.Join(outputdir, "stub") + + pbPackage, err := parser.GetPackage(fd, opt.Language) + if err != nil { + return err + } + pbOutDir = filepath.Join(stubDir, pbPackage) + os.MkdirAll(pbOutDir, os.ModePerm) + } + + opts := []pb.Option{ + pb.WithPb2ImportPath(fd.Pb2ImportPath), + pb.WithPkg2ImportPath(fd.Pkg2ImportPath), + pb.WithSecvEnabled(true), + } + // Generate ${protofile}.pb.validate.go + if !opt.RPCOnly { + err = pb.Protoc(opt.Protodirs, opt.Protofile, opt.Language, pbOutDir, opts...) + } else { + err = pb.Protoc(opt.Protodirs, opt.Protofile, opt.Language, outputdir, opts...) + } + return err +} diff --git a/plugin/validate_test.go b/plugin/validate_test.go new file mode 100644 index 0000000..554fc52 --- /dev/null +++ b/plugin/validate_test.go @@ -0,0 +1,98 @@ +package plugin + +import ( + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/paths" + "trpc.group/trpc-go/trpc-cmdline/util/pb" +) + +func TestPlugin_Validate(t *testing.T) { + u := &Validate{} + require.Equal(t, "validate", u.Name()) + + t.Run("!go", func(t *testing.T) { + require.False(t, u.Check(nil, ¶ms.Option{})) + }) + + // rpconly test + t.Run("validate && rpconly", func(t *testing.T) { + // setup, refer to pb related to validate under testcase directory. + pbf, fd, err := parseValidateSampleProtofile() + require.Nil(t, err) + output := t.TempDir() + + wd, _ := os.Getwd() + defer os.Chdir(wd) + + // setup, generate a pb.go file for the above pb files. + opt := ¶ms.Option{ + Protofile: "helloworld.proto", + Protodirs: []string{filepath.Clean(filepath.Join(wd, "../install")), filepath.Dir(pbf)}, + Language: "go", + RPCOnly: true, + OutputDir: output, + } + require.True(t, u.Check(fd, opt)) + + dir, err := paths.Locate(pb.ProtoTRPC) + require.Nil(t, err) + opt.Protodirs = append(append(opt.Protodirs, dir), + paths.ExpandSearch(dir)...) + + os.Chdir(filepath.Dir(pbf)) + require.Nil(t, u.Run(fd, opt)) + }) + + // !rpconly test + t.Run("validate && !rpconly", func(t *testing.T) { + pbf, fd, err := parseValidateSampleProtofile() + if err != nil { + panic(err) + } + output := t.TempDir() + + wd, _ := os.Getwd() + defer os.Chdir(wd) + + opt := ¶ms.Option{ + Protofile: "helloworld.proto", + Protodirs: []string{filepath.Clean(filepath.Join(wd, "../install")), filepath.Dir(pbf)}, + Language: "go", + RPCOnly: false, + OutputDir: output, + } + + p := gomonkey.ApplyFunc(pb.Protoc, func([]string, string, string, string, ...pb.Option) error { + return nil + }) + defer p.Reset() + + require.True(t, u.Check(fd, opt)) + require.Nil(t, u.Run(fd, opt)) + }) +} + +func parseValidateSampleProtofile() (string, *descriptor.FileDescriptor, error) { + wd, err := os.Getwd() + if err != nil { + return "", nil, err + } + // parse protofile + pbd := filepath.Clean(filepath.Join(wd, "../testcase/plugins/validate")) + pbf := filepath.Join(pbd, "helloworld.proto") + ins := filepath.Clean(filepath.Join(wd, "../install")) + fd, err := parser.ParseProtoFile("helloworld.proto", append([]string{pbd, ins}, paths.ExpandTRPCSearch(ins)...)) + if err != nil { + return "", fd, err + } + return pbf, fd, err +} diff --git a/testcase/apidocs/helloworld.proto b/testcase/apidocs/helloworld.proto new file mode 100644 index 0000000..d62c1da --- /dev/null +++ b/testcase/apidocs/helloworld.proto @@ -0,0 +1,105 @@ +syntax = "proto3"; +package helloworld; + +import "trpc/proto/trpc_options.proto"; +import "trpc/swagger/swagger.proto"; + +message HelloReq{ + // msg消息 + string msg = 1; + map msg_map = 2; + repeated Message1 msg_list = 3; + Message3 m3 = 4; + Number number = 5; + message InnerMsg { + repeated string name_list = 1; + } + InnerMsg inner_msg = 6; + int64 int64num = 7; + uint64 uint64num = 8; + fixed64 fixed64num = 9; + bool boolV = 10; + int32 int32num = 11; + Message3 m3_1 = 12; + Message3 m3_2 = 13; + HelloReq req = 14; + Message4 m4 = 15; +} + +message Message1 { + repeated Message2 m2_list = 1; +} + +message Message2 { + repeated Message3 m3 = 1; +} + +message Message3 { + repeated string f3 = 1; +} + +message Message4 { + Message5 m5 = 1; +} +message Message5 { + Message6 m6 = 1; +} +message Message6 { + Message4 m4 = 1; +} + +enum Number { + zero = 0; + one = 1; +} + +message HelloRsp{ + int32 err_code = 1; + string err_msg = 2; +} + +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.alias) = "/api/v1/helloworld"; + option(trpc.swagger) = { + title : "你好世界" + method: "get" + description: + "入参:msg\n" + "作用:用于演示 helloword\n" + params: { + name: "msg" + required: true + default: "my_msg" + } + params: { + name: "m3" + required: true + default: "{\"f3\":[\"1\", \"2\"]}" + } + params: { + name: "int64num" + required: true + default: "12" + } + params: { + name: "number" + default: "1" + } + params: { + name: "msg_list" + required: true + } + params: { + name: "boolV" + required: true + default: "true" + } + params: { + name: "int32num" + required: true + default: "-123" + } + }; + }; +} diff --git a/testcase/apidocs/helloworld_comment.proto b/testcase/apidocs/helloworld_comment.proto new file mode 100644 index 0000000..12881f7 --- /dev/null +++ b/testcase/apidocs/helloworld_comment.proto @@ -0,0 +1,106 @@ +syntax = "proto3"; +package helloworld; + +import "trpc/proto/trpc_options.proto"; +import "trpc/swagger/swagger.proto"; + +message HelloReq{ + // msg消息 + string msg = 1; + map msg_map = 2; + repeated Message1 msg_list = 3; + Message3 m3 = 4; + Number number = 5; + message InnerMsg { + repeated string name_list = 1; + } + InnerMsg inner_msg = 6; + int64 int64num = 7; + uint64 uint64num = 8; + fixed64 fixed64num = 9; + bool boolV = 10; + int32 int32num = 11; + Message3 m3_1 = 12; + Message3 m3_2 = 13; + HelloReq req = 14; + Message4 m4 = 15; +} + +message Message1 { + repeated Message2 m2_list = 1; +} + +message Message2 { + repeated Message3 m3 = 1; +} + +message Message3 { + repeated string f3 = 1; +} + +message Message4 { + Message5 m5 = 1; +} +message Message5 { + Message6 m6 = 1; +} +message Message6 { + Message4 m4 = 1; +} + +enum Number { + zero = 0; + one = 1; +} + +message HelloRsp{ + int32 err_code = 1; + string err_msg = 2; +} + +service helloworld_svr { + // @alias=/api/v1/helloworld + // @tags 111 + rpc Hello(HelloReq) returns(HelloRsp) { + option(trpc.swagger) = { + title : "你好世界" + method: "get" + description: + "入参:msg\n" + "作用:用于演示 helloword\n" + params: { + name: "msg" + required: true + default: "my_msg" + } + params: { + name: "m3" + required: true + default: "{\"f3\":[\"1\", \"2\"]}" + } + params: { + name: "int64num" + required: true + default: "12" + } + params: { + name: "number" + default: "1" + } + params: { + name: "msg_list" + required: true + } + params: { + name: "boolV" + required: true + default: "true" + } + params: { + name: "int32num" + required: true + default: "-123" + } + }; + }; +} diff --git a/testcase/apidocs/helloworld_restful.proto b/testcase/apidocs/helloworld_restful.proto new file mode 100644 index 0000000..0896a78 --- /dev/null +++ b/testcase/apidocs/helloworld_restful.proto @@ -0,0 +1,65 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "trpc/api/annotations.proto"; +import "trpc/swagger/swagger.proto"; + +// HelloReq request +message HelloReq{ + string name = 1; + uint64 id = 2; +} + +// HelloRsp response +message HelloRsp{ + int32 errcode = 1; +} + +// helloworld_svr handle hello request and echo message +service helloworld_svr { + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp) { + option (trpc.api.http) = { + get: "/hello/{name}" + additional_bindings: { + get: "/hello/id/{id}" + } + }; + option(trpc.swagger) = { + params: { + name: "id" + default: "1234" + } + params: { + name: "name" + default: "my_name1" + } + }; + }; + // Hello say hello + rpc Say(HelloReq) returns(HelloRsp) { + option (trpc.api.http) = { + post: "/say/{id}" + additional_bindings: { + post: "/say/body" + body: "*" + }; + additional_bindings: { + post: "/say/name" + body: "name" + }; + }; + option (trpc.swagger) = { + params: { + name: "id" + default: "1235" + } + params: { + name: "name" + default: "my_name2" + } + }; + }; +} \ No newline at end of file diff --git a/testcase/create/1-without-import/helloworld.proto b/testcase/create/1-without-import/helloworld.proto new file mode 100644 index 0000000..27d8b41 --- /dev/null +++ b/testcase/create/1-without-import/helloworld.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; +package helloworld; + +option go_package = "trpc.group/examples/helloworld"; +option java_package = "com.trpc.examples.helloworld"; + +// HelloReq is hello request. +message HelloReq{ + string msg = 1; +} + +// HelloRsp is hello response. +message HelloRsp{ + string msg = 1; +} + +// HelloWorldService handles hello request and echo message. +service HelloWorldService { + // Hello1 says hello. + rpc Hello1(HelloReq) returns(HelloRsp); + // Hello2 says hello. + rpc Hello2(HelloReq) returns(HelloRsp); // @alias=myhello2 +} + +// HelloWorldServerStreamService handles hello request and echo message. +service HelloWorldServerStreamService { + // Hello says hello. + rpc Hello(HelloReq) returns(stream HelloRsp); +} + +service HelloWorldBidiStreamService { + // Hello says hello. + rpc Hello(stream HelloReq) returns(stream HelloRsp); +} + +service HelloWroldClientStreamService { + // Hello says hello. + rpc Hello(stream HelloReq) returns(HelloRsp); +} diff --git a/testcase/create/10-validate/abc/abc.proto b/testcase/create/10-validate/abc/abc.proto new file mode 100644 index 0000000..87475ac --- /dev/null +++ b/testcase/create/10-validate/abc/abc.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package abc; + +import "trpc/validate/validate.proto"; +option go_package="trpc.group/helloworld/abc"; + +message AAA{ + string msg = 1 [(validate.rules).string.email = true]; +} diff --git a/testcase/create/10-validate/helloworld.proto b/testcase/create/10-validate/helloworld.proto new file mode 100644 index 0000000..6d222a7 --- /dev/null +++ b/testcase/create/10-validate/helloworld.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/helloworld"; + +import "abc/abc.proto"; +import "trpc/validate/validate.proto"; + +service HelloSvr { + rpc Hello(abc.AAA) returns(HelloResponse); +} + +message HelloRequest { + string msg = 1 [(validate.rules).string.email=true]; +} + +message HelloResponse { + int32 err_code = 1; + string err_msg = 2; +} + + diff --git a/testcase/create/11.same-service-same-import/Makefile b/testcase/create/11.same-service-same-import/Makefile new file mode 100644 index 0000000..7faad7b --- /dev/null +++ b/testcase/create/11.same-service-same-import/Makefile @@ -0,0 +1,16 @@ +# Usage: +# 1. Create stub files: make stub +# 2. Clean all the generated files: make clean + +.PHONY: stub clean + +stub: + go mod init trpc.group/examples/helloworld + trpc create -p common/common.proto -o common --rpconly --usebasename=false + trpc create -p service1/service1.proto -o service1 --rpconly --usebasename=false --nogomod + trpc create -p service2/service2.proto -o service2 --rpconly --usebasename=false --nogomod + +clean: + find . -name "*.go" -type f -delete + find . -name "*.mod" -type f -delete + find . -name "*.sum" -type f -delete diff --git a/testcase/create/11.same-service-same-import/common/common.proto b/testcase/create/11.same-service-same-import/common/common.proto new file mode 100644 index 0000000..9ebc833 --- /dev/null +++ b/testcase/create/11.same-service-same-import/common/common.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package helloworld.common; + +option go_package = "trpc.group/examples/helloworld/common"; +option java_package = "com.trpc.examples.helloworld"; + +// HelloReq is the hello request. +message HelloReq{ + string msg = 1; +} + +// HelloRsp is the hello response. +message HelloRsp{ + string msg = 1; +} diff --git a/testcase/create/11.same-service-same-import/service1/service1.proto b/testcase/create/11.same-service-same-import/service1/service1.proto new file mode 100644 index 0000000..4269b32 --- /dev/null +++ b/testcase/create/11.same-service-same-import/service1/service1.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package helloworld.service1; + +import "common/common.proto"; + +option go_package = "trpc.group/examples/helloworld/service1"; +option java_package = "com.trpc.examples.helloworld"; + +// HelloWorldService handle hello request and echo message. +service HelloWorldService { + // Hello says hello. + rpc Hello(helloworld.common.HelloReq) returns(helloworld.common.HelloRsp); +} diff --git a/testcase/create/11.same-service-same-import/service2/service2.proto b/testcase/create/11.same-service-same-import/service2/service2.proto new file mode 100644 index 0000000..380076d --- /dev/null +++ b/testcase/create/11.same-service-same-import/service2/service2.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package helloworld.service2; + +import "common/common.proto"; + +option go_package = "trpc.group/examples/helloworld/service2"; +option java_package = "com.trpc.examples.helloworld"; + +// HelloWorldService handle hello request and echo message. +service HelloWorldService { + // Hello says hello. + rpc Hello(helloworld.common.HelloReq) returns(helloworld.common.HelloRsp); +} diff --git a/testcase/create/2-multi-pb-same-package/hello.proto b/testcase/create/2-multi-pb-same-package/hello.proto new file mode 100644 index 0000000..8e12cad --- /dev/null +++ b/testcase/create/2-multi-pb-same-package/hello.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello"; + +import "message.proto"; + +service hello_svr { + rpc Hello (HelloReq) returns (HelloRsp); +} \ No newline at end of file diff --git a/testcase/create/2-multi-pb-same-package/message.proto b/testcase/create/2-multi-pb-same-package/message.proto new file mode 100644 index 0000000..fbf5f65 --- /dev/null +++ b/testcase/create/2-multi-pb-same-package/message.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello"; + +message HelloReq { +} + +message HelloRsp { +} \ No newline at end of file diff --git a/testcase/create/2.1-multi-pb-same-package-duplicate-proto/hello.proto b/testcase/create/2.1-multi-pb-same-package-duplicate-proto/hello.proto new file mode 100644 index 0000000..986531a --- /dev/null +++ b/testcase/create/2.1-multi-pb-same-package-duplicate-proto/hello.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello/proto"; + +import "message.proto"; + +service HelloWorldService { + rpc Hello (HelloReq) returns (HelloRsp); +} diff --git a/testcase/create/2.1-multi-pb-same-package-duplicate-proto/message.proto b/testcase/create/2.1-multi-pb-same-package-duplicate-proto/message.proto new file mode 100644 index 0000000..e407dee --- /dev/null +++ b/testcase/create/2.1-multi-pb-same-package-duplicate-proto/message.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; +package hello; + +option go_package="trpc.group/examples/hello/proto"; + +message HelloReq {} + +message HelloRsp {} diff --git a/testcase/create/3-multi-pb-diff-package/helloworld.proto b/testcase/create/3-multi-pb-diff-package/helloworld.proto new file mode 100644 index 0000000..60c0e77 --- /dev/null +++ b/testcase/create/3-multi-pb-diff-package/helloworld.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "request.proto"; +import "response.proto"; + +service HelloWorld { + rpc Hello(request.Request) returns(response.Response); +} \ No newline at end of file diff --git a/testcase/create/3-multi-pb-diff-package/request.proto b/testcase/create/3-multi-pb-diff-package/request.proto new file mode 100644 index 0000000..28cdf77 --- /dev/null +++ b/testcase/create/3-multi-pb-diff-package/request.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package request; + +option go_package="trpc.group/examples/request"; + +message Request{} \ No newline at end of file diff --git a/testcase/create/3-multi-pb-diff-package/response.proto b/testcase/create/3-multi-pb-diff-package/response.proto new file mode 100644 index 0000000..75b88e5 --- /dev/null +++ b/testcase/create/3-multi-pb-diff-package/response.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package response; + +option go_package="trpc.group/examples/response"; + +message Response{} \ No newline at end of file diff --git a/testcase/create/4.1-multi-pb-same-package-diff-protodir/helloworld.proto b/testcase/create/4.1-multi-pb-same-package-diff-protodir/helloworld.proto new file mode 100644 index 0000000..2042599 --- /dev/null +++ b/testcase/create/4.1-multi-pb-same-package-diff-protodir/helloworld.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "request/request.proto"; +import "response/response.proto"; + +service HelloWorld { + rpc Hello(Request) returns(Response); +} diff --git a/testcase/create/4.1-multi-pb-same-package-diff-protodir/request/request.proto b/testcase/create/4.1-multi-pb-same-package-diff-protodir/request/request.proto new file mode 100644 index 0000000..f11071c --- /dev/null +++ b/testcase/create/4.1-multi-pb-same-package-diff-protodir/request/request.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +message Request{} diff --git a/testcase/create/4.1-multi-pb-same-package-diff-protodir/response/response.proto b/testcase/create/4.1-multi-pb-same-package-diff-protodir/response/response.proto new file mode 100644 index 0000000..18060aa --- /dev/null +++ b/testcase/create/4.1-multi-pb-same-package-diff-protodir/response/response.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +message Response{} diff --git a/testcase/create/4.2-multi-pb-same-package-diff-protodir/helloworld.proto b/testcase/create/4.2-multi-pb-same-package-diff-protodir/helloworld.proto new file mode 100644 index 0000000..3307725 --- /dev/null +++ b/testcase/create/4.2-multi-pb-same-package-diff-protodir/helloworld.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "request.proto"; +import "response.proto"; + +service HelloWorld { + rpc Hello(Request) returns(Response); +} diff --git a/testcase/create/4.2-multi-pb-same-package-diff-protodir/request/request.proto b/testcase/create/4.2-multi-pb-same-package-diff-protodir/request/request.proto new file mode 100644 index 0000000..f11071c --- /dev/null +++ b/testcase/create/4.2-multi-pb-same-package-diff-protodir/request/request.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +message Request{} diff --git a/testcase/create/4.2-multi-pb-same-package-diff-protodir/response/response.proto b/testcase/create/4.2-multi-pb-same-package-diff-protodir/response/response.proto new file mode 100644 index 0000000..18060aa --- /dev/null +++ b/testcase/create/4.2-multi-pb-same-package-diff-protodir/response/response.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +message Response{} diff --git a/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/a.proto b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/a.proto new file mode 100644 index 0000000..2e06f86 --- /dev/null +++ b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/a.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; +package trpc.trpcprotocol.common; + +option java_package="com.tencent.trpcprotocol.common.aaa"; +option go_package ="trpc.group/trpcprotocol/common/aaa"; + +import "common/b.proto"; + +message A { + optional B b = 1; +} \ No newline at end of file diff --git a/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/b.proto b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/b.proto new file mode 100644 index 0000000..9b06b06 --- /dev/null +++ b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/common/b.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package trpc.trpcprotocol.common; + +option java_package = "com.tencent.trpcprotocol.common.bbb"; +option go_package = "trpc.group/trpcprotocol/common/bbb_common"; + +message B {} + diff --git a/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/helloworld.proto b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/helloworld.proto new file mode 100755 index 0000000..dc0de9d --- /dev/null +++ b/testcase/create/5-multi-pb-same-pkgdirective-diff-gopkgoption/helloworld.proto @@ -0,0 +1,21 @@ +syntax = "proto2"; +package trpc.trpcprotocol.common; + +option java_package = "com.tencent.trpcprotocol.helloworld"; +option go_package = "trpc.group/trpcprotocol/helloworld"; + +import "common/a.proto"; +import "common/b.proto"; + +service HelloService { + rpc Hello1(Request) returns (Response) {} // @alias=Hello1 + rpc Hello2(Request) returns (Response) {} // @alias=Hello2 +} + +message Request { + optional A a = 1; +} + +message Response { + optional B b = 1; +} diff --git a/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/cos/comm.proto b/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/cos/comm.proto new file mode 100644 index 0000000..ca49d52 --- /dev/null +++ b/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/cos/comm.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package cobus; +option go_package = "trpc.group/YottaIndex/YottaIndexClient/yotta_index_proto"; + +message AclInfo { + bytes key = 1; +} \ No newline at end of file diff --git a/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/pattern.proto b/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/pattern.proto new file mode 100644 index 0000000..43b7088 --- /dev/null +++ b/testcase/create/5.1-multi-pb-diff-pkgdirective-same-gopkgoption/pattern.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package yotta_index.pb; +option go_package = "trpc.group/YottaIndex/YottaIndexClient/yotta_index_proto"; + +import "cos/comm.proto"; + +message Param { + cobus.AclInfo acl = 1; +} + +service HelloService { + rpc Hello1(Param) returns (Param); +} diff --git a/testcase/create/6-other-scene/google/google.proto b/testcase/create/6-other-scene/google/google.proto new file mode 100644 index 0000000..7d75ea5 --- /dev/null +++ b/testcase/create/6-other-scene/google/google.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +import "google/protobuf/any.proto"; + +package helloworld; + +option go_package = "trpc.group/trpcprotocol/helloworld"; + +service HelloService { + rpc Hello(HelloRequest) returns (HelloResponse); +} + +message HelloRequest { +} + +message HelloResponse { + map info_map = 1; +} diff --git a/testcase/create/6-other-scene/hello_service/hello.proto b/testcase/create/6-other-scene/hello_service/hello.proto new file mode 100644 index 0000000..b45fd97 --- /dev/null +++ b/testcase/create/6-other-scene/hello_service/hello.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; +package trpc.test.helloworld; + +option go_package="trpc.group/trpcprotocol/test/helloworld"; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +message HelloRequest { + string msg = 1; +} + +message HelloReply { + string msg = 1; +} diff --git a/testcase/create/7-plugins/gotag/gotag.proto b/testcase/create/7-plugins/gotag/gotag.proto new file mode 100644 index 0000000..0e56ed6 --- /dev/null +++ b/testcase/create/7-plugins/gotag/gotag.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package trpc.test.gotag; + +option go_package = "trpc.group/trpcprotocol/test/gotag"; + +import "trpc/proto/trpc_options.proto"; + +service Greeter { + rpc SayHello(HelloRequest) returns(HelloReply) {} +} + +message HelloRequest { + string msg = 1 [(trpc.go_tag) = 'xml:"www"']; + int32 age = 2 [(trpc.go_tag) = 'json:"jjj"']; + int32 gender = 3 [(trpc.go_tag) = 'aaa:"bbb" ccc:"ddd"']; + message nestedLowercaseMessage { + string name = 1 [(trpc.go_tag) = 'toml:"name"']; + } + nestedLowercaseMessage others = 4 [(trpc.go_tag) = 'yml:"Others"']; + ; +} + +message testLowercaseMessage { string msg = 1 [(trpc.go_tag) = 'db:"msg"']; } + +message HelloReply { + string msg = 1; + message NestedMessageOne { + string nested_one = 1 [(trpc.go_tag) = 'yaml:"nested_one"']; + message NestedMessageTwo { + string nested_two = 1 [(trpc.go_tag) = 'yaml:"nested_two"']; + } + } + NestedMessageOne test = 2 [(trpc.go_tag) = 'yaml:"test"']; +} diff --git a/testcase/create/8-service-not-existed/helloworld.proto b/testcase/create/8-service-not-existed/helloworld.proto new file mode 100644 index 0000000..d2293ff --- /dev/null +++ b/testcase/create/8-service-not-existed/helloworld.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; +package helloworld; + +import "trpc/proto/trpc_options.proto"; + +option go_package="trpc.group/examples/helloworld"; + +// HelloReq request +message HelloReq{ + string name = 1 [(trpc.go_tag)='xml:"name"']; +} + +// HelloRsp response +message HelloRsp{} \ No newline at end of file diff --git a/testcase/create/9-restful/helloworld.proto b/testcase/create/9-restful/helloworld.proto new file mode 100644 index 0000000..c6f4664 --- /dev/null +++ b/testcase/create/9-restful/helloworld.proto @@ -0,0 +1,45 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; +option java_package = "com.tencent.trpc.helloworld"; + +import "trpc/api/annotations.proto"; + +// HelloReq request +message HelloReq{ + string name = 1; + uint64 id = 2; +} + +// HelloRsp response +message HelloRsp{ + int32 errcode = 1; +} + +// helloworld_svr handle hello request and echo message +service helloworld_svr { + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp) { + option (trpc.api.http) = { + get: "/hello/{name}" + additional_bindings: { + get: "/hello/id/{id}" + } + }; + }; + // Hello say hello + rpc Say(HelloReq) returns(HelloRsp) { + option (trpc.api.http) = { + post: "/say/{id}" + additional_bindings: { + post: "/say/body" + body: "*" + }; + additional_bindings: { + post: "/say/name" + body: "name" + }; + }; + }; +} \ No newline at end of file diff --git a/testcase/flatbuffers/1-without-import/helloworld.fbs b/testcase/flatbuffers/1-without-import/helloworld.fbs new file mode 100755 index 0000000..44b14bb --- /dev/null +++ b/testcase/flatbuffers/1-without-import/helloworld.fbs @@ -0,0 +1,19 @@ +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +// HelloReq request +table HelloReq{ + Message:string; +} + +// HelloRsp response +table HelloRsp{ + Message:string; +} + +// helloworld_svr handle hello request and echo message +rpc_service helloworld_svr { + // Hello say hello + Hello(HelloReq):HelloRsp; +} \ No newline at end of file diff --git a/testcase/flatbuffers/2-multi-fb-same-namespace/hello.fbs b/testcase/flatbuffers/2-multi-fb-same-namespace/hello.fbs new file mode 100755 index 0000000..5292603 --- /dev/null +++ b/testcase/flatbuffers/2-multi-fb-same-namespace/hello.fbs @@ -0,0 +1,9 @@ +include "message.fbs"; +namespace hello; + +attribute "go_package=trpc.group/examples/hello"; + + +rpc_service hello_svr { + Hello(HelloReq):HelloRsp; +} \ No newline at end of file diff --git a/testcase/flatbuffers/2-multi-fb-same-namespace/message.fbs b/testcase/flatbuffers/2-multi-fb-same-namespace/message.fbs new file mode 100755 index 0000000..0f537e0 --- /dev/null +++ b/testcase/flatbuffers/2-multi-fb-same-namespace/message.fbs @@ -0,0 +1,11 @@ +namespace hello; + +attribute "go_package=trpc.group/examples/hello"; + +table HelloReq { + Message:string; +} + +table HelloRsp { + Message:string; +} \ No newline at end of file diff --git a/testcase/flatbuffers/3-multi-fb-diff-namespace/helloworld.fbs b/testcase/flatbuffers/3-multi-fb-diff-namespace/helloworld.fbs new file mode 100755 index 0000000..aba3c11 --- /dev/null +++ b/testcase/flatbuffers/3-multi-fb-diff-namespace/helloworld.fbs @@ -0,0 +1,10 @@ +include "request.fbs"; +include "response.fbs"; + +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +rpc_service HelloWorld { + Hello(request.Request):response.Response; +} \ No newline at end of file diff --git a/testcase/flatbuffers/3-multi-fb-diff-namespace/request.fbs b/testcase/flatbuffers/3-multi-fb-diff-namespace/request.fbs new file mode 100755 index 0000000..0b4a902 --- /dev/null +++ b/testcase/flatbuffers/3-multi-fb-diff-namespace/request.fbs @@ -0,0 +1,7 @@ +namespace request; + +attribute "go_package=trpc.group/examples/request"; + +table Request{ + message:string; +} \ No newline at end of file diff --git a/testcase/flatbuffers/3-multi-fb-diff-namespace/response.fbs b/testcase/flatbuffers/3-multi-fb-diff-namespace/response.fbs new file mode 100755 index 0000000..86041b3 --- /dev/null +++ b/testcase/flatbuffers/3-multi-fb-diff-namespace/response.fbs @@ -0,0 +1,7 @@ +namespace response; + +attribute "go_package=trpc.group/examples/response"; + +table Response{ + message:string; +} \ No newline at end of file diff --git a/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/helloworld.fbs b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/helloworld.fbs new file mode 100755 index 0000000..47edfa7 --- /dev/null +++ b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/helloworld.fbs @@ -0,0 +1,10 @@ +include "request/request.fbs"; +include "response/response.fbs"; + +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +rpc_service HelloWorld { + Hello(Request):Response; +} diff --git a/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/request/request.fbs b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/request/request.fbs new file mode 100755 index 0000000..2086222 --- /dev/null +++ b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/request/request.fbs @@ -0,0 +1,7 @@ +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +table Request{ + Message:string; +} diff --git a/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/response/response.fbs b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/response/response.fbs new file mode 100755 index 0000000..38b377c --- /dev/null +++ b/testcase/flatbuffers/4.1-multi-fb-same-namespace-diff-dir/response/response.fbs @@ -0,0 +1,7 @@ +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +table Response{ + Message:string; +} diff --git a/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/helloworld.fbs b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/helloworld.fbs new file mode 100755 index 0000000..46e88b5 --- /dev/null +++ b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/helloworld.fbs @@ -0,0 +1,20 @@ +// 4.2 和 4.1 的区别在于 +// 4.2 的 include 里面不包含相对路径 +// 因此在生成 4.2 的桩代码时需要在命令行上加上要 include 的文件的路径 +// 如 +// trpc create --fbsdir testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/request \ +// --fbsdir testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/response \ +// --fbs testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/helloworld.fbs \ +// -o out-4-2 \ +// --mod trpc.group/testapp/testserver42 +include "request.fbs"; +include "response.fbs"; + +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + + +rpc_service HelloWorld { + Hello(Request):Response; +} diff --git a/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/request/request.fbs b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/request/request.fbs new file mode 100755 index 0000000..2086222 --- /dev/null +++ b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/request/request.fbs @@ -0,0 +1,7 @@ +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +table Request{ + Message:string; +} diff --git a/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/response/response.fbs b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/response/response.fbs new file mode 100755 index 0000000..38b377c --- /dev/null +++ b/testcase/flatbuffers/4.2-multi-fb-same-namespace-diff-dir/response/response.fbs @@ -0,0 +1,7 @@ +namespace helloworld; + +attribute "go_package=trpc.group/examples/helloworld"; + +table Response{ + Message:string; +} diff --git a/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs b/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs new file mode 100755 index 0000000..3556fc0 --- /dev/null +++ b/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs @@ -0,0 +1,26 @@ +namespace trpc.circlesearch.common_feedcloud_common; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_common"; + +// mapitem +table Entry { + key:string; + value:string; +} + +table BytesEntry { + key:string; + value:[ubyte]; +} + +table Result { + retCode:int; + msg:string; +} + +// 通用扩展字段,可以带mapkv和querystring +table StCommonExt { + mapInfo:[circlesearch.common_feedcloud_common.Entry]; + attachInfo:string; +} + diff --git a/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs b/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs new file mode 100755 index 0000000..ea6e334 --- /dev/null +++ b/testcase/flatbuffers/5-multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs @@ -0,0 +1,315 @@ +include "circlesearch/common/feedcloud/common.fbs"; + +namespace trpc.circlesearch.common_feedcloud_fbsmeta; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsmeta"; + +enum SyncStatus : int { + SYNC_TO_QZONE = 1, // 同步到空间 + SYNC_FROM_QZONE = 2, // 来自空间 +} + +enum FeedType : int { + TYPE_ACTIVE_FEED = 1, // 主动 feed + TYPE_NOTICE_FEED = 2, // 通知 feed + TYPE_RECOM_FEED = 3, // 推荐 feed + TYPE_ADV_FEED = 4, // 广告 feed +} + +// 关系链类型 +enum RelationType : int { + NO_RELATION = 0, // 没关系 + FOLLOW = 1, // 关注 + MUTUAL_FOLLOW = 2, // 相互关注 + UNCARE = 3, // 拉黑 + FOLLOWED = 4, // 被关注 +} + +// 写操作类型 +enum OperationType : int { + OPERATION_LIKE = 0, // 赞 + OPERATION_COMMENT = 1, // 评论 + OPERATION_REPLY = 2, // 回复 + OPERATION_SYSTEM = 3, // 系统 + OPERATION_FOLLOW = 4, // 关注 +} + +enum NoticeType : int { + TYPE_LIKE = 0, // 赞 + TYPE_COMMENT = 1, // 评论 + TYPE_REPLY = 2, // 回复 + TYPE_SYSTEM = 3, // 系统消息 + TYPE_FOLLOW = 4, // 关注 + // 后续业务可自行扩展 +} + +// StModifyFeedReq.mBitmap 值定义 +enum ModifyFeedBit : int { + MODIFY_FEED_STATUS = 1, // 修改视频状态 第一位 + MODIFY_FEED_CONTENT = 2, // 修改图文内容 第二位 +} + +table StIconInfo { + iconUrl40:string; + iconUrl100:string; + iconUrl140:string; + iconUrl640:string; + iconUrl:string; // 原图 +} + +// 用户信息 +table StUser { + id:string; // QQ 号 + nick:string; + icon:circlesearch.common_feedcloud_fbsmeta.StIconInfo; + desc:string; // 如果有账号描述,则显示账号描述;如果没有,则显示第一个作品标题 + followState:uint; // 登陆者对该用户的关注状态,0:未关注;1:已关注; + type:uint; // 用户类型,业务自己定义 + sex:uint; // 0 表示未知 1 表示男 2 表示女 + birthday:ulong; // 生日 + school:string; // 学校 + location:string; // 所在地 + busiData:[ubyte]; // 业务自行定义 +} + +// 图片挡位信息 +table StImageUrl { + levelType:uint; // 档位,0:原图, 1:小图, 2:中图, 3:大图 + url:string; + width:uint; + height:uint; + busiData:[ubyte]; // 业务自行定义 +} + +// 图片信息 +table StImage { + width:uint; + height:uint; + picUrl:string; + vecImageUrl:[circlesearch.common_feedcloud_fbsmeta.StImageUrl]; // 备选档位 + picId:string; // 图片 id + busiData:[ubyte]; // 业务自行定义 +} + +// 视频档位信息 +table StVideoUrl { + levelType:uint; // 档位,0:原档 + playUrl:string; // 播放地址 + videoPrior:uint; // 视频编码,0:未知;1:H264;2:H265软解;3:H265硬解; + videoRate:uint; // 视频码率kbps + transStatus:uint; // 转码状态,0:默认值;1:转码中;2:转码完成;3:转码失败; + busiData:[ubyte]; // 业务自行定义 +} + +// 视频信息 +table StVideo { + fileId:string; //* 流媒体平台的文件ID + fileSize:uint; //* 文件大小,单位字节 + duration:uint; //* 视频时长,单位毫秒 + width:uint; + height:uint; + playUrl:string; + transStatus:uint; // 转码状态,0:默认值;1:转码中;2:转码完成;3:转码失败; + videoPrior:uint; // 视频编码,0:未知;1:H264;2:H265软解;3:H265硬解; + videoRate:uint; // 视频码率kbps + vecVideoUrl:[circlesearch.common_feedcloud_fbsmeta.StVideoUrl]; // 备选档位 + busiData:[ubyte]; //业务自行定义 +} + +// 赞 +table StLike { + id:string; // 赞 ID + count:uint; // 点赞总数 + status:uint; // 是否点赞:0:否 1:是 + vecUser:[circlesearch.common_feedcloud_fbsmeta.StUser]; // 赞列表 + busiData:[ubyte]; // 业务自行定义 + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 操作人 +} + +// 回复 +table StReply { + id:string; + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; + createTime:ulong; // 发表必填,秒级时间戳 + content:string; + targetUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 被回复人 + busiData:[ubyte]; // 业务自行定义 +} + +// 评论 +table StComment { + id:string; + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表必填,秒级时间戳 + createTime:ulong; + content:string; + replyCount:uint; + vecReply:[circlesearch.common_feedcloud_fbsmeta.StReply]; + busiData:[ubyte]; // 业务自行定义 +} + +// 空间分享 +table StShareQzoneInfo { + entries:[circlesearch.common_feedcloud_common.Entry]; +} + +// 分享 +table StShare { + title:string; // 标题 + desc:string; // 描述 + type:uint; // 类型,业务自行定义 + url:string; // 详情 url + author:circlesearch.common_feedcloud_fbsmeta.StUser; // 作者信息 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 分享者信息 + cover:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + video:circlesearch.common_feedcloud_fbsmeta.StVideo; // 视频 + shorturl:string; // 分享短链接 + shareCardInfo:string; // json, 包含 AIO 分享卡片样式的必要信息 + shareQzoneInfo:circlesearch.common_feedcloud_fbsmeta.StShareQzoneInfo; // 分享空间内容 + busiData:[ubyte]; // 业务自行定义 +} + +// 浏览信息 +table StVisitor { + viewCount:uint; // 浏览量 + busiData:[ubyte]; // 业务自行定义 + recomCount:uint; // 被推荐的次数 +} + +// 转发区 +table StRecomForward { + id:string; + title:string; // 标题 + subtitle:string; // 副标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + createTime:ulong; // 发表时间,秒级时间戳 + type:uint; // 业务自行定义 + busiData:[ubyte]; // 业务自行定义 +} + +// feed 摘要 +table StFeedAbstract { + id:string; + title:string; // 标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + pic:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + type:uint; // 业务自行定义 + createTime:ulong; // 发表时间,秒级时间戳 +} + +// 标签信息 +table StTagInfo { + tagId:string; // 标签 id + tagName:string; // 标签名 + tagDec:string; // 描述信息 + userList:[circlesearch.common_feedcloud_fbsmeta.StUser]; // 用户预览列表 + feedList:[circlesearch.common_feedcloud_fbsmeta.StFeedAbstract]; // feed 预览列表 + tagTotalUser:uint; // 标签总成员数 + tagTotalFeed:uint; // 标签总 feed 数 +} + +// 推荐人信息 +table StUserRecomInfo { + user:circlesearch.common_feedcloud_fbsmeta.StUser; // 用户信息 + feedList:[circlesearch.common_feedcloud_fbsmeta.StFeedAbstract]; // feed 预览列表 +} + +// 异形feed,针对推荐、广告或者其他不能用StFeed标识的feed,使用StDittoFeed +table StDittoFeed { + dittoId:uint; // 异形feedId,唯一标识一种Feed,业务自定义 + dittoPatternId:uint; // 异形feed样式Id,业务自定义 + dittoData:[ubyte]; // 异形feed样式数据,业务自定义 +} + +// 用户的 GPS,默认值为非法值,用来表示没有 GPS +table StGPSV2 { + lat:long; // 纬度,实际值 * 1000000 + lon:long; // 经度,实际值 * 1000000 + eType:long; // GPS_WGS84; // 如果是从手机硬件读出来的,要设置此gps为WGS84 // 如果是SDK返回使用GPS_MARS + alt:long; // 海拨 +} + +// POI属性信息 +table StPoiInfoV2 { + poiId:string; // poiID + name:string; // poi名称 + poiType:int; // POI 类型 + typeName:string; // 类型名称 + address:string; // poi地址 + districtCode:int; // 行政区划编码,与身份证号前6位意义相同 + gps:circlesearch.common_feedcloud_fbsmeta.StGPSV2; // 定位的gps坐标 + distance:int; // 离输入点距离,单位:米 + hotValue:int; // 热度值 + phone:string; // 电话 + country:string; // 国家 + province:string; // 省、直辖市、自治区、特别行政区 + city:string; // 地区、地级市、自治州、盟 + poiNum:int; // poi排序位置 + poiOrderType:int; // poi优化类别 + defaultName:string; // 后台推荐的显示标题 + district:string; // 区 + dianPingId:string; // 点评POI ID +} + +// 动态内容 +table StFeed { + id:string; + title:string; // 标题 + subtitle:string; // 副标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + cover:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + video:circlesearch.common_feedcloud_fbsmeta.StVideo; // 视频 + content:string; // 图文内容 + type:uint; // feed 媒体类型,业务自行定义 + createTime:ulong; // 发表时间,秒级时间戳 + likeInfo:circlesearch.common_feedcloud_fbsmeta.StLike; // 赞信息 + commentCount:uint; // 评论总数 + vecComment:[circlesearch.common_feedcloud_fbsmeta.StComment]; // 评论列表 + share:circlesearch.common_feedcloud_fbsmeta.StShare; // 分享信息 + visitorInfo:circlesearch.common_feedcloud_fbsmeta.StVisitor; // 浏览信息 + images:[circlesearch.common_feedcloud_fbsmeta.StImage]; // 多图 + status:uint; // 业务自己定义 + poiInfo:circlesearch.common_feedcloud_fbsmeta.StPoiInfoV2; // POI 属性信息 + adBuffer:[ubyte]; // 广告 feed + busiData:[ubyte]; // 业务自行定义 + isRecomFd:bool; // 是否用户推荐转发 feed + recomForward:circlesearch.common_feedcloud_fbsmeta.StRecomForward; // 推荐转发区域 + tagInfos:[circlesearch.common_feedcloud_fbsmeta.StTagInfo]; // 标签信息 + syncStatus:uint; // 同步状态 + busiReport:[ubyte]; // 上报透传字段,读下发,上报带上 + dittoFeed:circlesearch.common_feedcloud_fbsmeta.StDittoFeed; // 异形 feed + feedType:uint; // feed 类型,见 FEED_TYPE + busiTransparent:[circlesearch.common_feedcloud_common.BytesEntry]; // feed 层面的透传字段,key 业务自行定义 +} + +// 关系链信息 +table StRelationInfo { + id:string; // 对方账号信息 + relation:uint; // 关系类型,见 RELATION_TYPE + busiData:[ubyte]; // 业务特有信息,结构体自行定义 +} + +// 写操作类型 +table StOperation { + opType:uint; // 操作类型,见 OPERATION_TYPE + opUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 操作人信息 + opTime:ulong; // 操作时间 + comment:circlesearch.common_feedcloud_fbsmeta.StComment; // 如果是评论或者回复,当前评论或者回复详情放这里 + like:circlesearch.common_feedcloud_fbsmeta.StLike; // 点赞信息 + busiData:[ubyte]; // 业务自行定义 +} + +// 被动通知 +table StNotice { + feedId:string; + noticeType:uint; // 通知类型,见 NOTICE_TYPE + createTime:ulong; // 通知时间,秒级时间戳 + operation:circlesearch.common_feedcloud_fbsmeta.StOperation; // 操作信息 + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; // feed 信息 + busiData:[ubyte]; // 业务自行定义 +} + +table StReportInfo { + id:string; // feed id + busiReport:[ubyte]; // 上报透传字段,对应StFeed busiReport +} + diff --git a/testcase/flatbuffers/5-multi-fb-diff-gopkg/fbsread.fbs b/testcase/flatbuffers/5-multi-fb-diff-gopkg/fbsread.fbs new file mode 100755 index 0000000..7c7b06e --- /dev/null +++ b/testcase/flatbuffers/5-multi-fb-diff-gopkg/fbsread.fbs @@ -0,0 +1,32 @@ +include "circlesearch/common/feedcloud/fbsmeta.fbs"; +include "circlesearch/common/feedcloud/common.fbs"; + +namespace trpc.circlesearch.common_feedcloud_fbsread; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsread"; + +table StGetFeedDetailReq { + extInfo:circlesearch.common_feedcloud_common.StCommonExt; +} + +table StGetFeedDetailRsp { + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; + vecRcmdFeed:[circlesearch.common_feedcloud_fbsmeta.StFeed]; + share:circlesearch.common_feedcloud_fbsmeta.StShare; +} + +table StGetFeedListReq { + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; +} + +table StGetFeedListRsp { + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + vecFeed:[circlesearch.common_feedcloud_fbsmeta.StFeed]; +} + +rpc_service ComReader { + GetFeedList(StGetFeedListReq):StGetFeedListRsp; + GetFeedDetail(StGetFeedDetailReq):StGetFeedDetailRsp; +} diff --git a/testcase/plugins/format/helloworld.pb.go.txt b/testcase/plugins/format/helloworld.pb.go.txt new file mode 100644 index 0000000..efa3697 --- /dev/null +++ b/testcase/plugins/format/helloworld.pb.go.txt @@ -0,0 +1,202 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.14.0 +// source: helloworld.proto + +package helloworld + +import ( + reflect "reflect" + sync "sync" + + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +// HelloReq request +type HelloReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *HelloReq) Reset() { + *x = HelloReq{} + if protoimpl.UnsafeEnabled { + mi := &file_helloworld_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloReq) ProtoMessage() {} + +func (x *HelloReq) ProtoReflect() protoreflect.Message { + mi := &file_helloworld_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloReq.ProtoReflect.Descriptor instead. +func (*HelloReq) Descriptor() ([]byte, []int) { + return file_helloworld_proto_rawDescGZIP(), []int{0} +} + +// HelloRsp response +type HelloRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *HelloRsp) Reset() { + *x = HelloRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_helloworld_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HelloRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HelloRsp) ProtoMessage() {} + +func (x *HelloRsp) ProtoReflect() protoreflect.Message { + mi := &file_helloworld_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HelloRsp.ProtoReflect.Descriptor instead. +func (*HelloRsp) Descriptor() ([]byte, []int) { + return file_helloworld_proto_rawDescGZIP(), []int{1} +} + +var File_helloworld_proto protoreflect.FileDescriptor + +var file_helloworld_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x0a, + 0x0a, 0x08, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x22, 0x0a, 0x0a, 0x08, 0x48, 0x65, + 0x6c, 0x6c, 0x6f, 0x52, 0x73, 0x70, 0x32, 0x45, 0x0a, 0x0e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, + 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x73, 0x76, 0x72, 0x12, 0x33, 0x0a, 0x05, 0x48, 0x65, 0x6c, 0x6c, + 0x6f, 0x12, 0x14, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, + 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x1a, 0x14, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, + 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x73, 0x70, 0x42, 0x4a, 0x0a, + 0x23, 0x67, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x6f, 0x61, 0x2e, 0x63, 0x6f, 0x6d, + 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, + 0x6f, 0x72, 0x6c, 0x64, 0x5a, 0x23, 0x67, 0x69, 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x6f, + 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, + 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_helloworld_proto_rawDescOnce sync.Once + file_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc +) + +func file_helloworld_proto_rawDescGZIP() []byte { + file_helloworld_proto_rawDescOnce.Do(func() { + file_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData) + }) + return file_helloworld_proto_rawDescData +} + +var file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_helloworld_proto_goTypes = []interface{}{ + (*HelloReq)(nil), // 0: helloworld.HelloReq + (*HelloRsp)(nil), // 1: helloworld.HelloRsp +} +var file_helloworld_proto_depIdxs = []int32{ + 0, // 0: helloworld.helloworld_svr.Hello:input_type -> helloworld.HelloReq + 1, // 1: helloworld.helloworld_svr.Hello:output_type -> helloworld.HelloRsp + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_helloworld_proto_init() } +func file_helloworld_proto_init() { + if File_helloworld_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HelloReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HelloRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_helloworld_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_helloworld_proto_goTypes, + DependencyIndexes: file_helloworld_proto_depIdxs, + MessageInfos: file_helloworld_proto_msgTypes, + }.Build() + File_helloworld_proto = out.File + file_helloworld_proto_rawDesc = nil + file_helloworld_proto_goTypes = nil + file_helloworld_proto_depIdxs = nil +} diff --git a/testcase/plugins/format/helloworld.proto b/testcase/plugins/format/helloworld.proto new file mode 100644 index 0000000..af9aeae --- /dev/null +++ b/testcase/plugins/format/helloworld.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; +option java_package="trpc.group.examples.helloworld"; + +// HelloReq request +message HelloReq{} + +// HelloRsp response +message HelloRsp{} + +// helloworld_svr handle hello request and echo message +service helloworld_svr { + // Hello say hello + rpc Hello(HelloReq) returns(HelloRsp); +} \ No newline at end of file diff --git a/testcase/plugins/format/helloworld.trpc.go.txt b/testcase/plugins/format/helloworld.trpc.go.txt new file mode 100644 index 0000000..98e7495 --- /dev/null +++ b/testcase/plugins/format/helloworld.trpc.go.txt @@ -0,0 +1,110 @@ +// Code generated by trpc-go/trpc-cmdline. DO NOT EDIT. +// source: helloworld.proto + +package helloworld + +import ( + "context" + "fmt" + + _ "trpc.group/trpc-go/trpc-go" + _ "trpc.group/trpc-go/trpc-go/http" + + "trpc.group/trpc-go/trpc-go/client" + "trpc.group/trpc-go/trpc-go/codec" + "trpc.group/trpc-go/trpc-go/server" +) + +/* ************************************ Service Definition ************************************ */ + +// HelloworldSvrService defines service +type HelloworldSvrService interface { + + // Hello Hello say hello + Hello(ctx context.Context, req *HelloReq, rsp *HelloRsp) (err error) +} + +func HelloworldSvrService_Hello_Handler(svr interface{}, ctx context.Context, f server.FilterFunc) (rspbody interface{}, err error) { + + req := &HelloReq{} + rsp := &HelloRsp{} + filters, err := f(req) + if err != nil { + return nil, err + } + handleFunc := func(ctx context.Context, reqbody interface{}, rspbody interface{}) error { + return svr.(HelloworldSvrService).Hello(ctx, reqbody.(*HelloReq), rspbody.(*HelloRsp)) + } + + err = filters.Handle(ctx, req, rsp, handleFunc) + if err != nil { + return nil, err + } + + return rsp, nil +} + +// HelloworldSvrServer_ServiceDesc descriptor for server.RegisterService +var HelloworldSvrServer_ServiceDesc = server.ServiceDesc{ + ServiceName: "helloworld.helloworld_svr", + HandlerType: ((*HelloworldSvrService)(nil)), + Methods: []server.Method{ + { + Name: "/helloworld.helloworld_svr/Hello", + Func: HelloworldSvrService_Hello_Handler, + }, + }, +} + +// RegisterHelloworldSvrService register service +func RegisterHelloworldSvrService(s server.Service, svr HelloworldSvrService) { + if err := s.Register(&HelloworldSvrServer_ServiceDesc, svr); err != nil { + panic(fmt.Sprintf("HelloworldSvr register error:%v", err)) + } + +} + +/* ************************************ Client Definition ************************************ */ + +// HelloworldSvrClientProxy defines service client proxy +type HelloworldSvrClientProxy interface { + + // Hello Hello say hello + Hello(ctx context.Context, req *HelloReq, opts ...client.Option) (rsp *HelloRsp, err error) +} + +type HelloworldSvrClientProxyImpl struct { + client client.Client + opts []client.Option +} + +var NewHelloworldSvrClientProxy = func(opts ...client.Option) HelloworldSvrClientProxy { + return &HelloworldSvrClientProxyImpl{client: client.DefaultClient, opts: opts} +} + +func (c *HelloworldSvrClientProxyImpl) Hello(ctx context.Context, req *HelloReq, opts ...client.Option) (rsp *HelloRsp, err error) { + + ctx, msg := codec.WithCloneMessage(ctx) + defer codec.PutBackMessage(msg) + + msg.WithClientRPCName("/helloworld.helloworld_svr/Hello") + msg.WithCalleeServiceName(HelloworldSvrServer_ServiceDesc.ServiceName) + msg.WithCalleeApp("") + msg.WithCalleeServer("") + msg.WithCalleeService("helloworld_svr") + msg.WithCalleeMethod("Hello") + msg.WithSerializationType(codec.SerializationTypePB) + + callopts := make([]client.Option, 0, len(c.opts)+len(opts)) + callopts = append(callopts, c.opts...) + callopts = append(callopts, opts...) + + rsp = &HelloRsp{} + + err = c.client.Invoke(ctx, req, rsp, callopts...) + if err != nil { + return nil, err + } + + return rsp, nil +} diff --git a/testcase/plugins/gotag/gotag.proto b/testcase/plugins/gotag/gotag.proto new file mode 100644 index 0000000..0e56ed6 --- /dev/null +++ b/testcase/plugins/gotag/gotag.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package trpc.test.gotag; + +option go_package = "trpc.group/trpcprotocol/test/gotag"; + +import "trpc/proto/trpc_options.proto"; + +service Greeter { + rpc SayHello(HelloRequest) returns(HelloReply) {} +} + +message HelloRequest { + string msg = 1 [(trpc.go_tag) = 'xml:"www"']; + int32 age = 2 [(trpc.go_tag) = 'json:"jjj"']; + int32 gender = 3 [(trpc.go_tag) = 'aaa:"bbb" ccc:"ddd"']; + message nestedLowercaseMessage { + string name = 1 [(trpc.go_tag) = 'toml:"name"']; + } + nestedLowercaseMessage others = 4 [(trpc.go_tag) = 'yml:"Others"']; + ; +} + +message testLowercaseMessage { string msg = 1 [(trpc.go_tag) = 'db:"msg"']; } + +message HelloReply { + string msg = 1; + message NestedMessageOne { + string nested_one = 1 [(trpc.go_tag) = 'yaml:"nested_one"']; + message NestedMessageTwo { + string nested_two = 1 [(trpc.go_tag) = 'yaml:"nested_two"']; + } + } + NestedMessageOne test = 2 [(trpc.go_tag) = 'yaml:"test"']; +} diff --git a/testcase/plugins/validate/helloworld.proto b/testcase/plugins/validate/helloworld.proto new file mode 100644 index 0000000..65f786b --- /dev/null +++ b/testcase/plugins/validate/helloworld.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package trpc.app.hello; +option go_package = "trpc.group/examples/helloworld"; + +import "trpc/validate/validate.proto"; + +message HelloRequest { + bool val = 1 [(validate.rules).bool.const = true]; +} + +message HelloResponse { + bool val = 1 [(validate.rules).bool.const = false]; +} + +service HelloService { + rpc Hello (HelloRequest) returns (HelloResponse); +} diff --git a/tpl/funcmap.go b/tpl/funcmap.go new file mode 100644 index 0000000..d273baf --- /dev/null +++ b/tpl/funcmap.go @@ -0,0 +1,74 @@ +// Package tpl encapsulates Go's template operations and +// supports generating stub codes and configurations based on template files. +package tpl + +import ( + "path/filepath" + "strings" + "text/template" + + "github.com/iancoleman/strcase" + + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/lang" +) + +// funcMap is a map of custom template functions used in Go templates. +var funcMap = template.FuncMap{ + // simplify simplifies a Go type based on protobuf type. + "simplify": lang.PBSimplifyGoType, + // gopkg returns the Go package name for a protobuf package. + "gopkg": lang.PBGoPackage, + // gopkg_simple returns a simplified version of the Go package name. + "gopkg_simple": lang.PBValidGoPackage, + // gotype returns the Go type for a protobuf type. + "gotype": lang.PBGoType, + // export returns the exported form of an identifier. + "export": lang.GoExport, + // gofulltype returns the fully qualified Go type. + "gofulltype": lang.GoFullyQualifiedType, + // gofulltypex returns the fully qualified Go type with special characters escaped. + "gofulltypex": lang.GoFullyQualifiedTypeX, + // title converts a string to title case. + "title": lang.Title, + // untitle converts a title case string to normal case. + "untitle": lang.UnTitle, + // trimright trims the right-side characters from a string. + "trimright": lang.TrimRight, + // trimleft trims the left-side characters from a string. + "trimleft": lang.TrimLeft, + // splitList splits a comma-separated list into an array. + "splitList": lang.SplitList, + // Reverse a list. + "reverse": lang.ReverseList, + // last returns the last element of an array or slice. + "last": lang.Last, + // hasprefix checks if a string has a given prefix. + "hasprefix": lang.HasPrefix, + // hassuffix checks if a string has a given suffix. + "hassuffix": lang.HasSuffix, + // contains checks if a string contains a given substring. + "contains": strings.Contains, + // add adds two integers. + "add": lang.Add, + // camelcase converts a string to camel case. + "camelcase": lang.Camelcase, + // lowercamelcase converts a string to lower camel case. + "lowercamelcase": strcase.ToLowerCamel, + // lower converts a string to lowercase. + "lower": strings.ToLower, + // snakecase converts a string to snake case. + "snakecase": strcase.ToSnake, + // secvtpl checks if a string is a secure template. + "secvtpl": lang.CheckSECVTpl, + // replace replaces all occurrences of a substring with another substring. + "replace": strings.ReplaceAll, + // concat concatenates multiple strings. + "concat": lang.Concat, + // mergerpc merges RPC paths. + "mergerpc": lang.MergeRPC, + // basenamewithoutext returns the base name of a file without the extension. + "basenamewithoutext": fs.BaseNameWithoutExt, + "dir": filepath.Dir, + "join": strings.Join, +} diff --git a/tpl/tpl.go b/tpl/tpl.go new file mode 100644 index 0000000..88a3ab3 --- /dev/null +++ b/tpl/tpl.go @@ -0,0 +1,319 @@ +// Package tpl encapsulates go's template operations and +// supports generating stub codes and configurations based on template files. +package tpl + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "text/template" + + "trpc.group/trpc-go/trpc-cmdline/config" + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" + + "github.com/iancoleman/strcase" + "github.com/pkg/errors" +) + +const ( + // ServiceIndexDefault represents the default value of the service index (by default, + // services are separated into different files, a valid value needs to be passed) + ServiceIndexDefault = 0 + // MethodIndexDefault represents the default value for service index (services are separated into different files, + // effective value is required) + MethodIndexDefault = -1 +) + +// FD is the a type alias of file descriptor. +type FD = descriptor.FileDescriptor + +// GenerateFiles processes the go template files and outputs them to the outputdir directory. +func GenerateFiles(fd *FD, outputdir string, option *params.Option) error { + // Preparing output directory. + if err := fs.PrepareOutputdir(outputdir); err != nil { + return fmt.Errorf("create outputdir: %v", err) + } + + // Template file extension name. + var cfg *config.Template + if option.OtherType == "" { + c, err := config.GetTemplate(option.IDLType, option.Language) + if err != nil { + return err + } + cfg = c + } + + // Traverse through the template files for processing. + f := func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if path == option.Assetdir { + return nil + } + mixed := MixedOptions{ + OutputDir: outputdir, + Cfg: cfg, + } + return ProcessTemplateFile(fd, path, info, option, &mixed) + } + return filepath.Walk(option.Assetdir, f) +} + +// GenerateOptions is extension options. +type GenerateOptions struct { + // Index position of the proto service, starting from 0, -1 means it doesn't exist. + serviceIndex int + // The index position of the service in proto, starting from 0, + // and -1 indicates that it does not exist. + methodIndex int +} + +// ServiceIndex returns the index of the service to be generated. +func (o *GenerateOptions) ServiceIndex() int { + if o != nil && o.serviceIndex >= 0 { + return o.serviceIndex + } + return ServiceIndexDefault +} + +// MethodIndex returns the index of the method to be generated. +func (o *GenerateOptions) MethodIndex() int { + if o != nil && o.methodIndex >= 0 { + return o.methodIndex + } + return MethodIndexDefault +} + +// GenerateFile generates file for fd. +func GenerateFile(fd *FD, infile, outfile string, opt *params.Option, extOpt *GenerateOptions) error { + if !filepath.IsAbs(opt.Assetdir) { + return errors.New("assetdir must be absolute path") + } + + // stat template + if _, err := os.Lstat(infile); err != nil { + return fmt.Errorf("lstat file err: %v", err) + } + + // create output file + fout, err := os.Create(outfile) + if err != nil { + return fmt.Errorf("create file err: %v", err) + } + defer fout.Close() + + // template execute and populate the output file + var tplInstance *template.Template + var baseName = filepath.Base(infile) + + if funcMap == nil { + tplInstance, err = template.New(baseName).ParseFiles(infile) + } else { + tplInstance, err = template.New(baseName).Funcs(funcMap).ParseFiles(infile) + } + if err != nil { + return fmt.Errorf("template initialize err: %v", err) + } + + // Pass in descriptor information, command-line control parameter information, + // and other serviceIndex information required by other split files. + err = tplInstance.Execute(fout, struct { + *descriptor.FileDescriptor + *params.Option + ServiceIndex int + MethodIndex int + TRPCCmdlineVersion string + }{ + fd, + opt, + extOpt.ServiceIndex(), + extOpt.MethodIndex(), + config.TRPCCliVersion, + }) + log.Debug("outfile:%s, genExtOption:%+v", outfile, extOpt) + + if err != nil { + return fmt.Errorf("template execute err: %v", err) + } + return nil +} + +// ProcessTemplateFile executes the Go template processing to generate a file +// based on the content of the entry template. +func ProcessTemplateFile(fd *FD, entry string, info os.FileInfo, option *params.Option, opts *MixedOptions) error { + log.Debug("file entry srcPath:%s", entry) + + // keep same files/folders hierarchy in the outputdir/assetdir + relPath := strings.TrimPrefix(entry, filepath.Clean(option.Assetdir)+string(filepath.Separator)) + if len(relPath) == 0 { + return nil + } + tplFileExt := config.GlobalConfig().TplFileExt + outPath := strings.TrimSuffix(filepath.Join(opts.OutputDir, relPath), tplFileExt) + log.Debug("file entry destPath: %s", outPath) + + // if `entry` is directory, create the same entry in `outputdir` + if info.IsDir() { + return os.MkdirAll(outPath, os.ModePerm) + } + // if `entry` is client/server stub + outdir := filepath.Dir(filepath.Join(opts.OutputDir, relPath)) + if opts.Cfg != nil { + if isServerStubFile(relPath, opts.Cfg.RPCServerStub) { + return generateServerStub(fd, entry, outdir, opts.Cfg, option) + } + if isServerTestStubFile(relPath, opts.Cfg.RPCServerTestStub) { + return generateServerTestStub(fd, entry, outdir, opts.Cfg.LangFileExt, option) + } + if isRPCClientStubFile(relPath, opts.Cfg.RPCClientStub) { + return generateClientStub(fd, entry, outdir, opts.Cfg, option) + } + } + // if `entry` is normal go template file + return GenerateFile(fd, entry, outPath, option, nil) +} + +func isServerStubFile(fp, serverStub string) bool { + stub := strings.ReplaceAll(serverStub, "/", string(filepath.Separator)) + return fp == stub +} + +func isServerTestStubFile(fp, serverTestStub string) bool { + stub := strings.ReplaceAll(serverTestStub, "/", string(filepath.Separator)) + return fp == stub +} + +func isRPCClientStubFile(fp string, rpcClientStub []string) bool { + for _, f := range rpcClientStub { + stub := strings.ReplaceAll(f, "/", string(filepath.Separator)) + if fp == stub { + return true + } + } + return false +} + +// generateServerStub generates server-side code corresponding to the service in the IDL. +func generateServerStub(fd *FD, infile, outdir string, cfg *config.Template, opt *params.Option) error { + if opt.PerMethod { + return generatePerMethod(fd, infile, outdir, cfg.LangFileExt, opt) + } + var camelcase bool + return generatePerService(fd, infile, outdir, cfg.LangFileExt, camelcase, opt) +} + +// generatePerService splits the generated code into separate files per service. +func generatePerService(fd *FD, infile, outdir, langFileExt string, camelcase bool, opt *params.Option) error { + for sIdx, sd := range fd.Services { + base := strcase.ToSnake(sd.Name) + "." + langFileExt + if camelcase { + base = strcase.ToCamel(sd.Name) + "." + langFileExt + } + outfile := filepath.Join(outdir, base) + if err := GenerateFile(fd, infile, outfile, opt, &GenerateOptions{sIdx, -1}); err != nil { + return err + } + } + return nil +} + +// generatePerMethod splits the generated code into separate files per method. +func generatePerMethod(fd *FD, inFile, outdir, langFileExt string, option *params.Option) error { + for sIdx, sd := range fd.Services { + for mIdx, method := range sd.RPC { + base := strcase.ToSnake(sd.Name) + "_" + strcase.ToSnake(method.Name) + "." + langFileExt + outfile := filepath.Join(outdir, base) + if err := GenerateFile(fd, inFile, outfile, option, &GenerateOptions{sIdx, mIdx}); err != nil { + return err + } + } + } + return nil +} + +// generateServerTestStub generates server-side test code for the service in the IDL. +func generateServerTestStub(fd *FD, entry, outdir, langFileExt string, option *params.Option) error { + for idx, sd := range fd.Services { + base := strcase.ToSnake(sd.Name) + "_test." + langFileExt + outfile := filepath.Join(outdir, base) + if err := GenerateFile(fd, entry, outfile, option, &GenerateOptions{serviceIndex: idx}); err != nil { + return err + } + log.Debug("entry destPath: %s", outfile) + continue + } + return nil +} + +// generateClientStub generates the client code corresponding to the service in the IDL. +func generateClientStub(fd *FD, infile, outdir string, cfg *config.Template, opt *params.Option) error { + // generate only one rpc stub file, which contains all services + if !cfg.RPCClientStubPerService { + base := strings.TrimSuffix(filepath.Base(infile), config.GlobalConfig().TplFileExt) + outPath := filepath.Join(outdir, base) + return GenerateFile(fd, infile, outPath, opt, nil) + } + + // generate rpc stub file per service + keepOrigName := cfg.KeepOrigName + camelcaseName := cfg.CamelCaseName + langFileExt := cfg.LangFileExt + + for idx, sd := range fd.Services { + var base string + if !keepOrigName { + base = strcase.ToSnake(sd.Name) + "." + langFileExt + if camelcaseName { + base = strcase.ToCamel(sd.Name) + "." + langFileExt + } + } else { + base = strcase.ToSnake(sd.Name) + cfg.Separator + fs.BaseNameWithoutExt(infile) + if camelcaseName { + base = strcase.ToCamel(sd.Name) + cfg.Separator + fs.BaseNameWithoutExt(infile) + } + } + outfile := filepath.Join(outdir, base) + if err := GenerateFile(fd, infile, outfile, opt, &GenerateOptions{idx, -1}); err != nil { + return err + } + } + return nil +} + +// GenerateFilePerService outputs clientStub by service splitting files. +func GenerateFilePerService(fd *FD, infile, outfile, stubName string, opt *params.Option) error { + cfg, err := config.GetTemplate(opt.IDLType, opt.Language) + if err != nil { + return err + } + + dir := filepath.Dir(outfile) + + for i, sd := range fd.Services { + var base string + if cfg.KeepOrigName { + base = fmt.Sprintf("%s%s%s.%s", strcase.ToCamel(sd.Name), cfg.Separator, stubName, cfg.Language) + } else { + base = fmt.Sprintf("%s%s.%s", strcase.ToSnake(sd.Name), cfg.Separator, cfg.Language) + } + + outfile = filepath.Join(dir, base) + extopt := &GenerateOptions{serviceIndex: i} + if err := GenerateFile(fd, infile, outfile, opt, extopt); err != nil { + return err + } + } + return nil +} + +// MixedOptions aggregates many options to simplify method signatures. +type MixedOptions struct { + OutputDir string + Cfg *config.Template +} diff --git a/trpc/trpc.go b/trpc/trpc.go new file mode 100644 index 0000000..bb9f1b9 --- /dev/null +++ b/trpc/trpc.go @@ -0,0 +1,24 @@ +/* +Copyright © 2020 zhijiezhang + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "trpc.group/trpc-go/trpc-cmdline/cmd" +) + +func main() { + cmd.Execute() +} diff --git a/util/apidocs/apidocs.go b/util/apidocs/apidocs.go new file mode 100644 index 0000000..1b190c4 --- /dev/null +++ b/util/apidocs/apidocs.go @@ -0,0 +1,42 @@ +// Package apidocs implements the ability to generate API documentation. +package apidocs + +import ( + "encoding/json" + "os" +) + +// ComponentStruct component struct +type ComponentStruct struct { + Schemas map[string]ModelStruct `json:"schemas"` +} + +// BodyContentStruct defines the structure of the response in OpenAPI JSON for a given method. +type BodyContentStruct struct { + Description string `json:"description"` // The description returned by method. + Content map[string]MediaStruct `json:"content,omitempty"` +} + +// MediaStruct defines the structure of the response in api docs json for a given method. +type MediaStruct struct { + Description string `json:"description,omitempty"` // The description returned by method. + // The reference to the data model for the method reference, must have. + Schema SchemaStruct `json:"schema,omitempty"` +} + +// SchemaStruct defines the structure of schema used by data model in api docs json. +type SchemaStruct struct { + Ref string `json:"$ref,omitempty"` + Properties []*PropertyStruct `json:"properties,omitempty"` +} + +// WriteJSON writes JSON. +func WriteJSON(file string, data interface{}) error { + // Format JSON file, ensure the strings output by json not write in one line. + jsonByte, err := json.MarshalIndent(data, "", " ") + if err != nil { + return err + } + + return os.WriteFile(file, jsonByte, 0666) +} diff --git a/util/apidocs/definitions.go b/util/apidocs/definitions.go new file mode 100644 index 0000000..22af049 --- /dev/null +++ b/util/apidocs/definitions.go @@ -0,0 +1,294 @@ +// Package apidocs provides functionality for handling API documentation. +// This package contains structures and methods related to generating API documentation in the +// apidocs JSON format. It includes models, definitions, and various utility functions. +package apidocs + +import ( + "fmt" + "strings" + + "github.com/jhump/protoreflect/desc" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// ModelStruct defines the structure of the whole data model in the apidocs JSON. +type ModelStruct struct { + Type string `json:"type"` // Data model type + Properties *Properties `json:"properties,omitempty"` // Data model parameters + Title string `json:"title,omitempty"` // Data model title + Description string `json:"description,omitempty"` // Data model description + AdditionalProperties *PropertyStruct `json:"additionalProperties,omitempty"` // Usage of map value + Ref string `json:"ref,omitempty"` + Items *PropertyStruct `json:"items,omitempty"` +} + +// Definitions models +type Definitions struct { + models map[string]ModelStruct +} + +var refPrefix = "#/definitions/" + +// GetNameByRef gets the name from a reference. +var GetNameByRef = func(ref string) string { + return strings.TrimPrefix(ref, refPrefix) +} + +// RefName returns a reference with the specified name. +var RefName = func(name string) string { + return fmt.Sprintf("%s%s", refPrefix, name) +} + +// NewDefinitions returns a Definition instance. +func NewDefinitions(option *params.Option, fds ...descriptor.Desc) *Definitions { + defs := &Definitions{ + models: map[string]ModelStruct{}, + } + + defs.addModelsByFDs(option, fds...) + return defs +} + +// props gets all properties of the model. +func (m ModelStruct) props() []*PropertyStruct { + var props []*PropertyStruct + + if m.Properties == nil { + return props + } + + m.Properties.orderedEach(func(k string, v PropertyStruct) { + prop := v + props = append(props, &prop) + if prop.Items != nil { + props = append(props, prop.Items) + } + }) + + if m.AdditionalProperties != nil { + props = append(props, m.AdditionalProperties) + if m.AdditionalProperties.Items != nil { + props = append(props, m.AdditionalProperties.Items) + } + } + return props +} + +// getUsedModels retrieves used models from paths. +func (defs *Definitions) getUsedModels(paths Paths) map[string]ModelStruct { + models := map[string]ModelStruct{} + + var usedRefs []string + paths.orderedEach(func(path string, pathsMethod Methods) { + pathsMethod.orderedEach(func(k string, method *MethodStruct) { + usedRefs = append(usedRefs, method.refs()...) + }) + }) + pos := 0 + searched := make(map[string]bool) + for { + if pos >= len(usedRefs) { + break + } + ref := usedRefs[pos] + pos++ + + if !defs.exist(ref) { + continue + } + def := defs.getModel(ref) + models[ref] = def + + for _, prop := range def.props() { + usedRefs = append(usedRefs, prop.refs(searched)...) + } + } + + return models +} + +// getModel retrieves a model by name. +func (defs *Definitions) getModel(name string) ModelStruct { + return defs.models[name] +} + +// addModel adds a model. +func (defs *Definitions) addModel(name string, model ModelStruct) { + defs.models[name] = model +} + +// exist is used to check whether a Model exists. +func (defs *Definitions) exist(name string) bool { + _, ok := defs.models[name] + return ok +} + +// addAdditionalModel adds an additional model to the Definitions. +// It takes the name and property of the model as input parameters. +func (defs *Definitions) addAdditionalModel(name string, property PropertyStruct) { + model := ModelStruct{ + Type: "object", + Title: name, + AdditionalProperties: &property, + } + + defs.addModel(name, model) +} + +// addModelsByMsg adds models to the Definitions based on the provided message descriptor. +// It takes an option, prefix name, and message descriptor as input parameters. +func (defs *Definitions) addModelsByMsg(option *params.Option, prefixName string, msg *desc.MessageDescriptor) { + name := prefixName + "." + msg.GetName() + description := strings.TrimSpace(msg.GetSourceInfo().GetLeadingComments()) + if description == "" { + description = msg.GetName() + } + model := ModelStruct{ + Type: "object", + Title: name, + Properties: NewProperties(option, msg, defs), + Description: description, + } + defs.addModel(name, model) + + for _, m := range msg.GetNestedMessageTypes() { + defs.addModelsByMsg(option, name, m) + } +} + +// addModelsByFDs adds models to the Definitions based on the provided file descriptors. +// It takes an option and one or more file descriptors as input parameters. +func (defs *Definitions) addModelsByFDs(option *params.Option, fds ...descriptor.Desc) { + for _, fd := range fds { + for _, msg := range fd.GetMessageTypes() { + messageDescriptor, ok := msg.(*descriptor.ProtoMessageDescriptor) + if !ok { + continue + } + + defs.addModelsByMsg(option, fd.GetPackage(), messageDescriptor.MD) + } + } +} + +// getMediaStruct returns a media struct for the given name. +// It takes the name of the struct as an input parameter and returns a map of media struct. +func (defs *Definitions) getMediaStruct(name string) map[string]MediaStruct { + if !defs.exist(name) { + return map[string]MediaStruct{} + } + def := defs.getModel(name) + return map[string]MediaStruct{ + "200": { + Description: def.Description, + Schema: SchemaStruct{ + Ref: RefName(name), + }, + }, + } +} + +// filterFields filters the fields of a model based on the provided suffix and fields. +// It takes the name, suffix, and fields as input parameters. +func (defs *Definitions) filterFields(name, suffix string, fields []string) { + if !defs.exist(name) || len(fields) == 0 { + return + } + + def := defs.getModel(name) + filters := map[string][]string{} + for _, f := range fields { + index := strings.Index(f, ".") + if index == -1 { + filters[f] = []string{} + continue + } + filters[f[:index]] = append(filters[f[:index]], f[index+1:]) + } + + newDef := ModelStruct{ + Type: def.Type, + Title: def.Title + "." + suffix, + Description: def.Description, + AdditionalProperties: def.AdditionalProperties, + } + + if len(def.Properties.Elements) != 0 { + newDef.Properties = &Properties{ + Elements: map[string]PropertyStruct{}, + } + if def.Properties.Rank != nil { + newDef.Properties.Rank = map[string]int{} + } + } + + def.Properties.orderedEach(func(name string, p PropertyStruct) { + fields, ok := filters[name] + + if ok && len(fields) == 0 { + return + } + + if len(fields) == 0 { + newDef.Properties.Put(name, p) + return + } + + // There is a next level. + refName := GetNameByRef(p.Ref) + defs.filterFields(refName, suffix, fields) + p.Ref = RefName(refName + "." + suffix) + if defs.exist(refName + "." + suffix) { + newDef.Properties.Put(name, p) + } + }) + + if len(newDef.Properties.Elements) > 0 { + defs.addModel(newDef.Title, newDef) + } +} + +// getBodyParameters returns the body parameters for the given name. +// It takes the name of the struct as an input parameter and returns an array of body parameters. +func (defs *Definitions) getBodyParameters(name string) []*ParametersStruct { + if !defs.exist(name) { + return []*ParametersStruct{} + } + + return []*ParametersStruct{{ + Name: "requestBody", + In: "body", + Required: false, // Set as non-required field by default. + Schema: &SchemaStruct{ + Ref: RefName(name), + }, + }} +} + +// getBodyParameter returns the body parameter for the given name and field. +// It takes the name and field of the struct as input parameters and returns a body parameter. +func (defs *Definitions) getBodyParameter(name, field string) *ParametersStruct { + def := defs.getModel(name) + param := def.Properties.Elements[field].GetQueryParameter(field) + param.In = "body" + return param +} + +// getQueryParameters returns the query parameters for the given name. +// It takes the name of the struct as an input parameter and returns an array of query parameters. +func (defs *Definitions) getQueryParameters(name string) []*ParametersStruct { + var params []*ParametersStruct + + if !defs.exist(name) { + return params + } + + def := defs.getModel(name) + def.Properties.orderedEach(func(k string, prop PropertyStruct) { + params = append(params, prop.GetQueryParameters(prop.Title, defs, map[string]bool{name: true})...) + }) + + return params +} diff --git a/util/apidocs/info.go b/util/apidocs/info.go new file mode 100644 index 0000000..0b9d957 --- /dev/null +++ b/util/apidocs/info.go @@ -0,0 +1,32 @@ +package apidocs + +import ( + "fmt" + "path/filepath" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" +) + +// InfoStruct defines the structure of the documentation description information contained in the apidocs header. +type InfoStruct struct { + Title string `json:"title"` // Title of the doc. + Description string `json:"description,omitempty"` // Description of the doc. + Version string `json:"version,omitempty"` // Version of the doc. +} + +// NewInfo inits Info instance. +func NewInfo(fd *descriptor.FileDescriptor) (InfoStruct, error) { + filePath, err := filepath.Abs(fd.FilePath) + if err != nil { + return InfoStruct{}, err + } + _, fileName := filepath.Split(filePath) + title := strings.ReplaceAll(fileName, ".proto", "") + infoMap := InfoStruct{ + Title: title, + Description: fmt.Sprintf("The api document of %s", fileName), + Version: "2.0", + } + return infoMap, nil +} diff --git a/util/apidocs/info_test.go b/util/apidocs/info_test.go new file mode 100644 index 0000000..1c788e8 --- /dev/null +++ b/util/apidocs/info_test.go @@ -0,0 +1,67 @@ +package apidocs + +import ( + "fmt" + "path/filepath" + "reflect" + "testing" + + "github.com/agiledragon/gomonkey" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" +) + +func TestNewInfo(t *testing.T) { + type args struct { + fd *descriptor.FileDescriptor + } + tests := []struct { + name string + args args + want InfoStruct + wantErr bool + absError error + }{ + { + name: "case1-file_path_abs_error", + args: args{ + fd: &descriptor.FileDescriptor{}, + }, + want: InfoStruct{}, + wantErr: true, + absError: fmt.Errorf("error"), + }, + { + name: "case2-success", + args: args{ + fd: &descriptor.FileDescriptor{ + FilePath: "user.proto", + }, + }, + want: InfoStruct{ + Title: "user", + Description: "The api document of user.proto", + Version: "2.0", + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc(filepath.Abs, + func(path string) (string, error) { + return tt.args.fd.FilePath, tt.absError + }) + defer p.Reset() + + got, err := NewInfo(tt.args.fd) + if (err != nil) != tt.wantErr { + t.Errorf("NewInfo() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewInfo() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/util/apidocs/method.go b/util/apidocs/method.go new file mode 100644 index 0000000..f07c0d9 --- /dev/null +++ b/util/apidocs/method.go @@ -0,0 +1,146 @@ +package apidocs + +import "sort" + +// MethodStruct defines the detailed information of a method in apidocs. +type MethodStruct struct { + Summary string `json:"summary"` // Comments of method. + OperationID string `json:"operationId"` // Name of method. + Responses map[string]MediaStruct `json:"responses"` // Response. + Parameters []*ParametersStruct `json:"parameters"` // Parameters. + Tags []string `json:"tags"` // The service to which the method belongs. + Description string `json:"description,omitempty"` // Description of the method. +} + +// Methods is the set of methods. +type Methods struct { + Elements map[string]*MethodStruct + Rank map[string]int +} + +// Put inserts an element into the ordered map, and records the element's rank in "Rank". +func (methods *Methods) Put(key string, value *MethodStruct) { + methods.Elements[key] = value + + if methods.Rank != nil { + if _, ok := methods.Rank[key]; !ok { + methods.Rank[key] = len(methods.Elements) + } + } +} + +// UnmarshalJSON deserializes JSON data. +func (methods *Methods) UnmarshalJSON(b []byte) error { + return OrderedUnmarshalJSON(b, &methods.Elements, &methods.Rank) +} + +// MarshalJSON serializes the method to JSON. +func (methods Methods) MarshalJSON() ([]byte, error) { + return OrderedMarshalJSON(methods.Elements, methods.Rank) +} + +func (methods *Methods) orderedEach(f func(k string, m *MethodStruct)) { + if methods == nil { + return + } + + var keys []string + for k := range methods.Elements { + keys = append(keys, k) + } + + if methods.Rank != nil { + sort.Slice(keys, func(i, j int) bool { + return methods.Rank[keys[i]] < methods.Rank[keys[j]] + }) + } else { + sort.Strings(keys) + } + + for _, k := range keys { + f(k, methods.Elements[k]) + } +} + +func (m MethodStruct) refs() []string { + var refs []string + for _, responses := range m.Responses { + if len(responses.Schema.Ref) > 0 { + refs = append(refs, GetNameByRef(responses.Schema.Ref)) + } + } + for _, parameter := range m.Parameters { + if parameter.Schema != nil && len(parameter.Schema.Ref) > 0 { + refs = append(refs, GetNameByRef(parameter.Schema.Ref)) + } + if parameter.Items != nil { + refs = append(refs, parameter.Items.refs(map[string]bool{})...) + } + } + return refs +} + +// GetMethodX converts MethodStruct to OpenAPI v3 interface. +func (m MethodStruct) GetMethodX() *MethodStructX { + methodX := &MethodStructX{ + Summary: m.Summary, + OperationID: m.OperationID, + Responses: map[string]BodyContentStruct{}, + RequestBody: nil, + Tags: m.Tags, + Description: m.Description, + } + + // Returned values. + for status, r := range m.Responses { + resp := BodyContentStruct{ + Description: r.Description, + Content: map[string]MediaStruct{ + "application/json": { + Schema: r.Schema, + }, + }, + } + methodX.Responses[status] = resp + } + + // Parameters. + var props []*PropertyStruct + for _, param := range m.Parameters { + if param.In != "body" { + methodX.Parameters = append(methodX.Parameters, param.GetParametersStructX()) + continue + } + + if param.Schema != nil && param.Schema.Ref != "" { + methodX.RequestBody = param.GetRequestBody() + continue + } + + props = append(props, param.GetProperty()) + } + + if len(props) != 0 { + methodX.RequestBody = &BodyContentStruct{ + Content: map[string]MediaStruct{ + "application/json": { + Schema: SchemaStruct{ + Properties: props, + }, + }, + }, + } + } + + return methodX +} + +// GetMethodsX converts MethodStruct to OpenAPI v3 interface. +func (methods Methods) GetMethodsX() MethodsX { + methodsX := MethodsX{Elements: map[string]*MethodStructX{}} + methodsX.Rank = methods.Rank + methods.orderedEach(func(name string, method *MethodStruct) { + methodsX.Elements[name] = method.GetMethodX() + }) + return methodsX +} diff --git a/util/apidocs/openapi/gen.go b/util/apidocs/openapi/gen.go new file mode 100644 index 0000000..00933a7 --- /dev/null +++ b/util/apidocs/openapi/gen.go @@ -0,0 +1,19 @@ +// Package openapi provides the ability to manipulate OpenAPI documents. +package openapi + +import ( + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs" +) + +// GenOpenAPI provides external structure used to generate openapi json. +func GenOpenAPI(fd *descriptor.FileDescriptor, option *params.Option) error { + // Assemble the entire JSON information. + openapi, err := apidocs.NewOpenAPIJSON(fd, option) + if err != nil { + return err + } + + return apidocs.WriteJSON(option.OpenAPIOut, openapi) +} diff --git a/util/apidocs/openapi/gen_test.go b/util/apidocs/openapi/gen_test.go new file mode 100644 index 0000000..3c568ae --- /dev/null +++ b/util/apidocs/openapi/gen_test.go @@ -0,0 +1,65 @@ +package openapi + +import ( + "fmt" + "testing" + + "github.com/agiledragon/gomonkey" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs" +) + +func TestGenOpenAPI(t *testing.T) { + type args struct { + fd *descriptor.FileDescriptor + option *params.Option + } + tests := []struct { + name string + args args + wantErr bool + newErr error + }{ + { + name: "case1: new err", + args: args{ + fd: &descriptor.FileDescriptor{}, + option: ¶ms.Option{}, + }, + wantErr: true, + newErr: fmt.Errorf("err"), + }, + { + name: "case1: without err", + args: args{ + fd: &descriptor.FileDescriptor{}, + option: ¶ms.Option{}, + }, + wantErr: false, + newErr: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc( + apidocs.NewOpenAPIJSON, + func(fd *descriptor.FileDescriptor, option *params.Option) (*apidocs.OpenAPIJSON, error) { + return &apidocs.OpenAPIJSON{}, tt.newErr + }, + ).ApplyFunc( + apidocs.WriteJSON, + func(file string, data interface{}) error { + return nil + }, + ) + + defer p.Reset() + + if err := GenOpenAPI(tt.args.fd, tt.args.option); (err != nil) != tt.wantErr { + t.Errorf("GenOpenAPI() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/util/apidocs/openapi_v3.go b/util/apidocs/openapi_v3.go new file mode 100644 index 0000000..3d9ab5e --- /dev/null +++ b/util/apidocs/openapi_v3.go @@ -0,0 +1,50 @@ +package apidocs + +import ( + "fmt" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// OpenAPIJSON defines the structure of the JSON file that OpenAPI API documentation needs to load. +type OpenAPIJSON struct { + OpenAPI string `json:"openapi"` // Version of OpenAPI. + Info InfoStruct `json:"info"` // Description of the API documentation. + + Paths PathsX `json:"paths"` // Set of specific information for request methods. + // Definitions of various model data models, + // including method input and output parameter's structure definitions. + Components ComponentStruct `json:"components"` +} + +// NewOpenAPIJSON returns a new OpenAPIJSON instance. +func NewOpenAPIJSON(fd *descriptor.FileDescriptor, option *params.Option) (*OpenAPIJSON, error) { + refPrefix = "#/components/schemas/" + if fd.FD == nil { + return nil, fmt.Errorf("nil fd") + } + + defs := NewDefinitions(option, append(fd.FD.GetDependencies(), fd.FD)...) + + // Assemble the information of each method. + paths := NewPaths(fd, option, defs) + pathsX := paths.GetPathsX() + + // Get file's information for assemble header information of Swagger JSON doc. + info, err := NewInfo(fd) + if err != nil { + return nil, err + } + + openapi := &OpenAPIJSON{ + OpenAPI: "3.0.2", + Info: info, + Paths: pathsX, + Components: ComponentStruct{ + Schemas: defs.getUsedModels(paths), + }, + } + + return openapi, nil +} diff --git a/util/apidocs/openapi_v3_test.go b/util/apidocs/openapi_v3_test.go new file mode 100644 index 0000000..855b18d --- /dev/null +++ b/util/apidocs/openapi_v3_test.go @@ -0,0 +1,165 @@ +package apidocs + +import ( + "encoding/json" + "os" + + "testing" + + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/paths" +) + +func TestNewOpenAPIJSON(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/submodules", + "../../install/submodules/trpc-protocol", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + openapi, err := NewOpenAPIJSON(fd, option) + require.NoError(t, err) + + gotByte, err := json.MarshalIndent(openapi, "", " ") + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/openapi.json") + require.NoError(t, err) + require.Equal(t, string(wantByte), string(gotByte)) +} + +func TestNewOpenAPIJSON_OptJSONParam(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/submodules", + "../../install/submodules/trpc-protocol", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + SwaggerOptJSONParam: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + openapi, err := NewOpenAPIJSON(fd, option) + require.NoError(t, err) + + gotByte, err := json.MarshalIndent(openapi, "", " ") + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/openapi_json_param.json") + require.NoError(t, err) + require.Equal(t, string(wantByte), string(gotByte)) +} + +func TestNewOpenAPIJSON_OrderByPBName(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/submodules", + "../../install/submodules/trpc-protocol", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + OrderByPBName: true, + SwaggerOptJSONParam: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + openapi, err := NewOpenAPIJSON(fd, option) + require.NoError(t, err) + + gotByte, err := json.MarshalIndent(openapi, "", " ") + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/openapi_order_by_pbname.json") + + require.NoError(t, err) + require.Equal(t, string(wantByte), string(gotByte)) +} + +func TestNewOpenAPIJSON_Unmarshal(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/submodules", + "../../install/submodules/trpc-protocol", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + OrderByPBName: true, + SwaggerOptJSONParam: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + gotOpenapi, err := NewOpenAPIJSON(fd, option) + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/openapi_order_by_pbname.json") + var wantOpenapi = &OpenAPIJSON{} + err = json.Unmarshal(wantByte, wantOpenapi) + require.NoError(t, err) + + require.NoError(t, err) + require.Equal(t, wantOpenapi, gotOpenapi) +} diff --git a/util/apidocs/ordered_map.go b/util/apidocs/ordered_map.go new file mode 100644 index 0000000..2bf0f66 --- /dev/null +++ b/util/apidocs/ordered_map.go @@ -0,0 +1,83 @@ +package apidocs + +import ( + "bytes" + "encoding/json" + "reflect" + "sort" +) + +// OrderedUnmarshalJSON deserializes JSON data while preserving the order of keys. +func OrderedUnmarshalJSON(b []byte, element interface{}, rank interface{}) error { + if err := json.Unmarshal(b, element); err != nil { + return err + } + + elemObject := reflect.ValueOf(element).Elem() + index := make(map[string]int, elemObject.Len()) + keys := make([]string, 0, elemObject.Len()) + for _, key := range elemObject.MapKeys() { + keys = append(keys, key.String()) + nk, _ := json.Marshal(key.String()) // Escape the key + index[key.String()] = bytes.Index(b, nk) + } + + // Sort keys based on their occurrence index in the JSON data. + sort.Slice(keys, func(i, j int) bool { + return index[keys[i]] < index[keys[j]] + }) + + rankObject := reflect.ValueOf(rank).Elem() + if rankObject.IsNil() { + rankObject.Set(reflect.MakeMap(rankObject.Type())) + } + + // Assign rank values to keys based on their sorted order. + for idx, key := range keys { + rankObject.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(idx+1)) + } + + return nil +} + +// OrderedMarshalJSON serializes data to JSON while preserving the order of keys. +func OrderedMarshalJSON(element interface{}, rank map[string]int) ([]byte, error) { + if len(rank) == 0 { + return json.Marshal(element) + } + + var keys []string + elemObject := reflect.ValueOf(element) + for _, key := range elemObject.MapKeys() { + keys = append(keys, key.String()) + } + + // Sort keys based on their rank values. + sort.Slice(keys, func(i, j int) bool { + return rank[keys[i]] < rank[keys[j]] + }) + + buf := &bytes.Buffer{} + buf.WriteRune('{') + l := len(keys) + for idx, key := range keys { + k, err := json.Marshal(key) + if err != nil { + return nil, err + } + buf.Write(k) + buf.WriteRune(':') + + v, err := json.Marshal(elemObject.MapIndex(reflect.ValueOf(key)).Interface()) + if err != nil { + return nil, err + } + buf.Write(v) + + if idx != l-1 { + buf.WriteRune(',') + } + } + buf.WriteRune('}') + return buf.Bytes(), nil +} diff --git a/util/apidocs/ordered_map_test.go b/util/apidocs/ordered_map_test.go new file mode 100644 index 0000000..74d5758 --- /dev/null +++ b/util/apidocs/ordered_map_test.go @@ -0,0 +1,145 @@ +package apidocs + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestOrderedMarshalJSON(t *testing.T) { + type args struct { + element interface{} + rank map[string]int + } + tests := []struct { + name string + args args + want []byte + wantErr require.ErrorAssertionFunc + }{ + { + name: "marshal", + args: args{ + element: map[string]string{ + "1": "value-1", + "2": "value-2", + "3": "value-3", + }, + rank: map[string]int{ + "1": 1, + "2": 2, + "3": 3, + }, + }, + want: []byte(`{"1":"value-1","2":"value-2","3":"value-3"}`), + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + { + name: "marshal in another order", + args: args{ + element: map[string]string{ + "1": "value-1", + "2": "value-2", + "3": "value-3", + }, + rank: map[string]int{ + "2": 1, + "1": 2, + "3": 3, + }, + }, + want: []byte(`{"2":"value-2","1":"value-1","3":"value-3"}`), + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + { + name: "marshal in standard order", + args: args{ + element: map[string]string{ + "2": "value-2", + "1": "value-1", + "3": "value-3", + }, + rank: map[string]int{}, + }, + want: []byte(`{"1":"value-1","2":"value-2","3":"value-3"}`), + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := OrderedMarshalJSON(tt.args.element, tt.args.rank) + tt.wantErr(t, err, fmt.Sprintf("OrderedMarshalJSON(%v, %v)", tt.args.element, tt.args.rank)) + require.Equalf(t, tt.want, got, "OrderedMarshalJSON(%v, %v)", tt.args.element, tt.args.rank) + }) + } +} + +func TestOrderedUnmarshalJSON(t *testing.T) { + type args struct { + b []byte + element interface{} + rank interface{} + } + var emptyRank map[string]int + tests := []struct { + name string + args args + wantErr require.ErrorAssertionFunc + }{ + { + name: "unmarshal", + args: args{ + b: []byte(`{"2":"value-2","1":"value-1","3":"value-3"}`), + element: &map[string]string{}, + rank: &map[string]int{}, + }, + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + { + name: "unmarshal_with_nil", + args: args{ + b: []byte(`{"2":"value-2","1":"value-1","3":"value-3"}`), + element: &map[string]string{}, + rank: &emptyRank, + }, + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + { + name: "unmarshal_rank", + args: args{ + b: []byte(`{ + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }`), + element: &map[string]interface{}{}, + rank: &emptyRank, + }, + wantErr: func(t require.TestingT, err error, i ...interface{}) { + require.NoError(t, err) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.wantErr(t, OrderedUnmarshalJSON(tt.args.b, tt.args.element, tt.args.rank), + fmt.Sprintf("OrderedUnmarshalJSON(%v, %v, %v)", tt.args.b, tt.args.element, tt.args.rank)) + }) + } +} diff --git a/util/apidocs/parameter.go b/util/apidocs/parameter.go new file mode 100644 index 0000000..e3ab8c6 --- /dev/null +++ b/util/apidocs/parameter.go @@ -0,0 +1,77 @@ +package apidocs + +// ParametersStruct defines the structure of input parameters information for methods in Swagger JSON format. +type ParametersStruct struct { + Name string `json:"name"` // Name of the parameter. + // Parameter's passing method: in, query, path, header, form. + In string `json:"in"` + Required bool `json:"required"` // Whether the parameter is required or not. + Type string `json:"type,omitempty"` // Type of parameter. + Schema *SchemaStruct `json:"schema,omitempty"` // Parameter reference, optional. + Format string `json:"format,omitempty"` // Parameter format, optional. + Description string `json:"description,omitempty"` // Parameter description, optional. + Enum []int32 `json:"enum,omitempty"` // Possible values for the enum. + // When type = array, it is necessary to indicate the member type, that is, the description of a single field value. + Items *PropertyStruct `json:"items,omitempty"` + Default interface{} `json:"default,omitempty"` // Default value of the parameter. +} + +// ParameterStructX for v3. +type ParameterStructX struct { + Name string `json:"name"` // Name of the parameter. + // Parameter's passing method: in, query, path, header, form. + In string `json:"in"` + Required bool `json:"required"` // Whether the parameter is required or not. + Description string `json:"description,omitempty"` // Parameter description. + Schema *ModelStruct `json:"schema,omitempty"` // Parameter reference. +} + +// GetParametersStructX converts the structure. +func (param ParametersStruct) GetParametersStructX() *ParameterStructX { + ref := "" + if param.Schema != nil { + ref = param.Schema.Ref + } + return &ParameterStructX{ + Name: param.Name, + In: param.In, + Required: param.Required, + Description: param.Description, + Schema: &ModelStruct{ + Type: param.Type, + Title: param.Name, + Description: param.Description, + AdditionalProperties: nil, + Ref: ref, + Items: param.Items, + }, + } +} + +// GetRequestBody converts the structure. +func (param ParametersStruct) GetRequestBody() *BodyContentStruct { + return &BodyContentStruct{ + Content: map[string]MediaStruct{ + "application/json": { + Schema: *param.Schema, + }, + }, + } +} + +// GetProperty converts the structure. +func (param ParametersStruct) GetProperty() *PropertyStruct { + ref := "" + if param.Schema != nil { + ref = param.Schema.Ref + } + return &PropertyStruct{ + Title: param.Name, + Type: param.Type, + Format: param.Format, + Ref: ref, + Description: param.Description, + Enum: param.Enum, + Items: param.Items, + } +} diff --git a/util/apidocs/path.go b/util/apidocs/path.go new file mode 100644 index 0000000..4f87bc4 --- /dev/null +++ b/util/apidocs/path.go @@ -0,0 +1,299 @@ +package apidocs + +import ( + "crypto/md5" + "fmt" + "regexp" + "sort" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// Paths is the set of Path. +type Paths struct { + Elements map[string]Methods + Rank map[string]int +} + +// Put puts the element into the ordered map and records the element's ranking order in "Rank". +func (paths *Paths) Put(key string, value Methods) { + paths.Elements[key] = value + + if paths.Rank != nil { + if _, ok := paths.Rank[key]; !ok { + paths.Rank[key] = len(paths.Elements) + } + } +} + +// UnmarshalJSON deserializes JSON data +func (paths *Paths) UnmarshalJSON(b []byte) error { + return OrderedUnmarshalJSON(b, &paths.Elements, &paths.Rank) +} + +// MarshalJSON serializes to JSON +func (paths Paths) MarshalJSON() ([]byte, error) { + return OrderedMarshalJSON(paths.Elements, paths.Rank) +} + +// NewPaths inits Path. +func NewPaths(fd *descriptor.FileDescriptor, option *params.Option, defs *Definitions) Paths { + paths := Paths{ + Elements: map[string]Methods{}, + } + + if option.OrderByPBName { + paths.Rank = map[string]int{} + } + + for _, service := range fd.Services { + for _, rpc := range append(service.RPC, service.RPCx...) { + args := methodArgs{ + RPC: rpc, + Defs: defs, + Opt: option, + } + args.Tags = []string{strings.ToLower(service.Name) + "." + "trpc"} + paths.addRPCMethod(args) + + args.Tags = []string{strings.ToLower(service.Name) + "." + "restful"} + paths.addRestfulMethod(args) + } + } + + paths.cleanOperationID() + return paths +} + +// methodArgs adds a method to Paths with the given method arguments. +type methodArgs struct { + RPC *descriptor.RPCDescriptor + Defs *Definitions + Tags []string + Opt *params.Option +} + +func (args methodArgs) summary() string { + // Get the description of each rpc method defined in front (if any). + summary := args.RPC.LeadingComments + // Verify the names of the rpc methods collected in the "option" previously. + if len(args.RPC.SwaggerInfo.Title) != 0 { + summary = args.RPC.SwaggerInfo.Title + } + return summary +} + +func (args methodArgs) method() *MethodStruct { + return &MethodStruct{ + Summary: args.summary(), + OperationID: args.RPC.Name, + Responses: args.Defs.getMediaStruct(args.RPC.ResponseType), + Tags: args.Tags, + Description: args.RPC.SwaggerInfo.Description, + } +} + +func (args methodArgs) rpcParams() []*ParametersStruct { + queryParams := args.Defs.getQueryParameters(args.RPC.RequestType) + if args.Opt.SwaggerOptJSONParam { + queryParams = args.Defs.getBodyParameters(args.RPC.RequestType) + } + + args.fillDescriptorToParams(queryParams) + return queryParams +} + +func (args methodArgs) restfulParams(api descriptor.RESTfulAPIContent) []*ParametersStruct { + pathParams := newPathParams(api.PathTmpl) + + names := pathParams.getNames() + reqType := args.RPC.RequestType + if len(names) > 0 { + suffix := fmt.Sprintf("%x", md5.Sum([]byte(api.PathTmpl))) + args.Defs.filterFields(reqType, suffix, names) + reqType += "." + suffix + } + + params := pathParams.getParameters() + method := strings.ToLower(api.Method) + + if api.RequestBody == "" && (method == "get" || method == "delete") { + params = append(params, args.Defs.getQueryParameters(reqType)...) + } + + if api.RequestBody == "*" { + params = append(params, args.Defs.getBodyParameters(reqType)...) + } + + if api.RequestBody != "" && api.RequestBody != "*" { + params = append(params, args.Defs.getBodyParameter(reqType, api.RequestBody)) + } + + args.fillDescriptorToParams(params) + + return params +} + +func (args methodArgs) fillDescriptorToParams(params []*ParametersStruct) { + for _, param := range params { + spd, ok := args.RPC.SwaggerInfo.Params[param.Name] + if ok { + param.Required = spd.Required + if spd.Default != "" { + param.Default = spd.Default + } + } + } +} + +// GetPathsX converts to openapi v3 structure. +func (paths Paths) GetPathsX() PathsX { + pathsX := PathsX{Elements: map[string]MethodsX{}} + pathsX.Rank = paths.Rank + paths.orderedEach(func(path string, methods Methods) { + pathsX.Elements[path] = methods.GetMethodsX() + }) + return pathsX +} + +func (paths Paths) addRPCMethod(args methodArgs) { + method := args.method() + method.Parameters = args.rpcParams() + + mx := Methods{Elements: map[string]*MethodStruct{}} + if paths.Rank != nil { + mx.Rank = map[string]int{} + } + mx.Put(args.RPC.SwaggerInfo.Method, method) + paths.Put(args.RPC.FullyQualifiedCmd, mx) +} + +func (paths Paths) addRestfulMethod(args methodArgs) { + for _, api := range args.RPC.RESTfulAPIInfo.ContentList { + // Filter out the existing paths + path := api.PathTmpl + pathParams := newPathParams(api.PathTmpl) + for _, param := range pathParams { + if param.value != "" { + path = strings.Replace(path, param.origin, param.value, -1) + } + } + + method := args.method() + method.Parameters = args.restfulParams(*api) + + mx, ok := paths.Elements[path] + if !ok { + mx = Methods{ + Elements: map[string]*MethodStruct{}, + } + if paths.Rank != nil { + mx.Rank = map[string]int{} + } + } + + mx.Put(strings.ToLower(api.Method), method) + paths.Put(path, mx) + } +} + +// orderedEach sort each element +func (paths *Paths) orderedEach(f func(path string, methods Methods)) { + if paths == nil { + return + } + + var keys []string + for k := range paths.Elements { + keys = append(keys, k) + } + + if paths.Rank != nil { + sort.Slice(keys, func(i, j int) bool { + return paths.Rank[keys[i]] < paths.Rank[keys[j]] + }) + } else { + sort.Strings(keys) + } + + for _, k := range keys { + f(k, paths.Elements[k]) + } +} + +// cleanOperationID adds a suffix number to the end of the OperationID to avoid duplication. +// The reason for using "order each" is that the loop over the map is random, +// which leads to unstable results and cannot be tested stably. +func (paths Paths) cleanOperationID() { + operationIDSet := make(map[string]int) + paths.orderedEach(func(path string, methods Methods) { + methods.orderedEach(func(k string, method *MethodStruct) { + operationIDSet[method.OperationID]++ + if operationIDSet[method.OperationID] > 1 { + method.OperationID = fmt.Sprintf("%s%d", + method.OperationID, operationIDSet[method.OperationID]) + } + }) + }) +} + +type pathParam struct { + name string + value string + origin string +} + +type pathParams []pathParam + +func (params pathParams) getParameters() []*ParametersStruct { + parameters := make([]*ParametersStruct, 0) + for _, param := range params { + if param.value != "" { + continue + } + + parameters = append(parameters, &ParametersStruct{ + Name: param.name, + Default: "", + Required: true, + Type: "string", + In: "path", + }) + } + + return parameters +} + +func (params pathParams) getNames() []string { + var names []string + for _, param := range params { + names = append(names, param.name) + } + return names +} + +var pathParamsRE = regexp.MustCompile("{.*?}") + +func newPathParams(path string) pathParams { + var params []pathParam + values := pathParamsRE.FindAllString(path, -1) + + for _, v := range values { + pos := strings.Index(v, "=") + if pos == -1 { + params = append(params, pathParam{ + origin: v, + name: v[1 : len(v)-1], + }) + continue + } + params = append(params, pathParam{ + origin: v, + name: v[1:pos], + value: v[pos+1 : len(v)-1], + }) + } + return params +} diff --git a/util/apidocs/pathx.go b/util/apidocs/pathx.go new file mode 100644 index 0000000..6cce651 --- /dev/null +++ b/util/apidocs/pathx.go @@ -0,0 +1,47 @@ +package apidocs + +// MethodStructX defines the detailed information of a method in OpenAPI JSON. +type MethodStructX struct { + Summary string `json:"summary,omitempty"` // Comment of method. + OperationID string `json:"operationId,omitempty"` // Name of method. + Responses map[string]BodyContentStruct `json:"responses,omitempty"` // Response definition of method. + + // Structure of method's input parameters except body. + Parameters []*ParameterStructX `json:"parameters,omitempty"` + RequestBody *BodyContentStruct `json:"requestBody,omitempty"` // Struct definition of method input parameters. + + Tags []string `json:"tags,omitempty"` // The service to which the method belongs. + Description string `json:"description,omitempty"` // Description of the method. +} + +// MethodsX for v3 +type MethodsX struct { + Elements map[string]*MethodStructX + Rank map[string]int +} + +// UnmarshalJSON deserializes JSON data. +func (method *MethodsX) UnmarshalJSON(b []byte) error { + return OrderedUnmarshalJSON(b, &method.Elements, &method.Rank) +} + +// MarshalJSON serializes to JSON. +func (method MethodsX) MarshalJSON() ([]byte, error) { + return OrderedMarshalJSON(method.Elements, method.Rank) +} + +// PathsX for v3 +type PathsX struct { + Elements map[string]MethodsX + Rank map[string]int +} + +// UnmarshalJSON deserializes JSON data. +func (paths *PathsX) UnmarshalJSON(b []byte) error { + return OrderedUnmarshalJSON(b, &paths.Elements, &paths.Rank) +} + +// MarshalJSON serializes to JSON. +func (paths PathsX) MarshalJSON() ([]byte, error) { + return OrderedMarshalJSON(paths.Elements, paths.Rank) +} diff --git a/util/apidocs/property.go b/util/apidocs/property.go new file mode 100644 index 0000000..40f2bbf --- /dev/null +++ b/util/apidocs/property.go @@ -0,0 +1,265 @@ +package apidocs + +import ( + "fmt" + "reflect" + "sort" + "strings" + + "github.com/jhump/protoreflect/desc" + protobuf "google.golang.org/protobuf/types/descriptorpb" + + "trpc.group/trpc-go/trpc-cmdline/params" + + "trpc.group/trpc-go/trpc-cmdline/util/apidocs/x" +) + +// PropertyStruct defines the structure of a single field of a data model in the api docs json. +type PropertyStruct struct { + Title string `json:"title,omitempty"` // Name of parameter. + Type string `json:"type,omitempty"` // Type of parameter. + Format string `json:"format,omitempty"` // Format of parameter. + Ref string `json:"$ref,omitempty"` // References in parameter. + Description string `json:"description,omitempty"` // Description of paramaeter. + Enum []int32 `json:"enum,omitempty"` // Possible values of the enum type. + // When type is array, specify the member type, i.e., the description of a single field value. + Items *PropertyStruct `json:"items,omitempty"` +} + +// Properties Properties +type Properties struct { + Elements map[string]PropertyStruct + Rank map[string]int +} + +// Put puts an element into an ordered map and records the order of the elements in Rank. +func (props *Properties) Put(key string, value PropertyStruct) { + props.Elements[key] = value + + if props.Rank != nil { + if _, ok := props.Rank[key]; !ok { + props.Rank[key] = len(props.Elements) + } + } +} + +// UnmarshalJSON deserializes JSON data. +func (props *Properties) UnmarshalJSON(b []byte) error { + return OrderedUnmarshalJSON(b, &props.Elements, &props.Rank) +} + +// MarshalJSON serializes to JSON. +func (props Properties) MarshalJSON() ([]byte, error) { + return OrderedMarshalJSON(props.Elements, props.Rank) +} + +// orderedEach traverses in order. +func (props *Properties) orderedEach(f func(k string, prop PropertyStruct)) { + if props == nil { + return + } + + var keys []string + for k := range props.Elements { + keys = append(keys, k) + } + + if props.Rank != nil { + sort.Slice(keys, func(i, j int) bool { + return props.Rank[keys[i]] < props.Rank[keys[j]] + }) + } else { + sort.Strings(keys) + } + + for _, k := range keys { + f(k, props.Elements[k]) + } +} + +func (p PropertyStruct) refs(searched map[string]bool) []string { + if searched[p.Ref] { + // Circular reference exists. + return nil + } + + var refs []string + if len(p.Ref) > 0 { + refs = append(refs, GetNameByRef(p.Ref)) + searched[p.Ref] = true + } + + if p.Items == nil { + return refs + } + + return append(refs, p.Items.refs(searched)...) +} + +// NewPropertyFunc factory +type NewPropertyFunc func(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct + +// NewProperties new +func NewProperties(option *params.Option, msg *desc.MessageDescriptor, defs *Definitions) *Properties { + if len(msg.GetFields()) == 0 { + return nil + } + + // Get message's field information and fill in properties. + propertiesMap := &Properties{ + Elements: map[string]PropertyStruct{}, + } + + if option.OrderByPBName { + propertiesMap.Rank = make(map[string]int) + } + + for _, field := range msg.GetFields() { + propertiesMap.Put(field.GetName(), NewProperty(field, defs)) + } + + return propertiesMap +} + +// NewProperty new +func NewProperty(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct { + property := newPropertyFactory(field)(field, defs) + + if property.Ref == "" || len(property.Title) == 0 { + property.Title = field.GetName() + } + + if !field.IsRepeated() { + return property + } + + p := property + property.Items = &PropertyStruct{ + Type: p.Type, + Format: p.Format, + } + + if p.Ref != "" { + property.Items = &PropertyStruct{Ref: p.Ref} + } + property.Ref = "" + property.Type = "array" + + return property +} + +func newPropertyFactory(field *desc.FieldDescriptor) NewPropertyFunc { + isMsg := field.GetType() == protobuf.FieldDescriptorProto_TYPE_MESSAGE + + switch { + case field.GetType() == protobuf.FieldDescriptorProto_TYPE_ENUM: + return newEnumProperty + case field.IsMap(): + return newMapProperty + case isMsg: + return newMessageProperty + default: + return newBasicProperty + } +} + +func newBasicProperty(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct { + // Get comment of field. + var descriptions []string + field.GetSourceInfo().GetLeadingDetachedComments() + descriptions = append(descriptions, strings.TrimSpace(field.GetSourceInfo().GetLeadingComments())) + descriptions = append(descriptions, strings.TrimSpace(field.GetSourceInfo().GetTrailingComments())) + + return PropertyStruct{ + Type: x.GetTypeStr(field.GetType()), + Format: x.GetFormatStr(field.GetType()), + Description: strings.TrimSpace(strings.Join(descriptions, "\n")), + } +} + +func newEnumProperty(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct { + property := newBasicProperty(field, defs) + enums := field.GetEnumType().GetValues() + if len(enums) == 0 { + return property + } + + for _, enum := range enums { + desc := fmt.Sprintf("%d - %s - %s", + enum.GetNumber(), + enum.GetName(), + strings.TrimSpace(enum.GetSourceInfo().GetTrailingComments()), + ) + property.Enum = append(property.Enum, enum.GetNumber()) + property.Description += " * " + desc + "\n" + } + + return property +} + +func newMessageProperty(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct { + return PropertyStruct{ + Ref: RefName(field.GetMessageType().GetFullyQualifiedName()), + Description: field.GetSourceInfo().GetLeadingComments() + field.GetSourceInfo().GetTrailingComments(), + } +} + +func newMapProperty(field *desc.FieldDescriptor, defs *Definitions) PropertyStruct { + name := strings.TrimSuffix(field.GetMessageType().GetFullyQualifiedName(), "entry") + + mapValueField := field.GetMapValueType() + mapAdditionProperties := PropertyStruct{} + if mapValueField.GetType() == protobuf.FieldDescriptorProto_TYPE_MESSAGE { + // For map values that are message types, use reflection to get the actual type + rMapValue := reflect.ValueOf(mapValueField) + rProto := reflect.Indirect(rMapValue).FieldByName("proto") + rTypeName := reflect.Indirect(rProto).FieldByName("TypeName") + typeName := fmt.Sprint(rTypeName.Elem())[1:] + mapAdditionProperties.Ref = RefName(typeName) + } else { + mapAdditionProperties = newBasicProperty(mapValueField, defs) + } + + defs.addAdditionalModel(name, mapAdditionProperties) + return PropertyStruct{ + Type: x.GetTypeStr(field.GetType()), + Ref: RefName(name), + Description: strings.TrimSpace(field.GetSourceInfo().GetLeadingComments()), + } +} + +// GetQueryParameter converts the given parameters into a query parameter string. +func (p PropertyStruct) GetQueryParameter(name string) *ParametersStruct { + return &ParametersStruct{ + Required: false, // Set to non-required field by default. + Name: name, + In: "query", + Schema: nil, + Type: p.Type, + Format: p.Format, + Description: p.Description, + Enum: p.Enum, + Items: p.Items, + } +} + +// GetQueryParameters converts the given parameters into a query parameter string. +func (p PropertyStruct) GetQueryParameters(name string, defs *Definitions, + searched map[string]bool) []*ParametersStruct { + + var params []*ParametersStruct + if p.Type != "message" && p.Type != "object" && p.Type != "" { + return append(params, p.GetQueryParameter(name)) + } + refName := GetNameByRef(p.Ref) + def := defs.getModel(refName) + if searched[refName] { + return append(params, p.GetQueryParameter(name)) + } + searched[refName] = true + def.Properties.orderedEach(func(k string, prop PropertyStruct) { + params = append(params, prop.GetQueryParameters(name+"."+k, defs, searched)...) + }) + delete(searched, refName) + return params +} diff --git a/util/apidocs/swagger.go b/util/apidocs/swagger.go new file mode 100644 index 0000000..5254771 --- /dev/null +++ b/util/apidocs/swagger.go @@ -0,0 +1,67 @@ +package apidocs + +import ( + "fmt" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" +) + +// SwaggerJSON defines the structure of the JSON that contains the swagger API documentation. +type SwaggerJSON struct { + Swagger string `json:"swagger"` // Version of Swagger. + Info InfoStruct `json:"info"` // Description information of the API document. + + Consumes []string `json:"consumes"` + Produces []string `json:"produces"` + + // A collection of detailed information for the request method. + Paths Paths `json:"paths"` + // Various model definitions, including the structure definitions of method input and output parameters. + Definitions map[string]ModelStruct `json:"definitions"` +} + +// NewSwagger swagger init +func NewSwagger(fd *descriptor.FileDescriptor, option *params.Option) (*SwaggerJSON, error) { + refPrefix = "#/definitions/" + if fd.FD == nil { + return nil, fmt.Errorf("nil fd") + } + + // Get the data model obtained from the pb file. + defs := NewDefinitions(option, append(allDependenciesFds(fd.FD), fd.FD)...) + + // Assemble the information of each method. + paths := NewPaths(fd, option, defs) + + // Get file information to assemble Swagger JSON document header information. + infoMap, err := NewInfo(fd) + if err != nil { + return nil, err + } + + // AssembleSwaggerJSON assembles the complete Swagger JSON document. + swaggerJSON := &SwaggerJSON{ + Swagger: "2.0", + Info: infoMap, + Consumes: []string{"application/json"}, + Produces: []string{"application/json"}, + Paths: paths, + Definitions: defs.getUsedModels(paths), + } + return swaggerJSON, nil +} + +func allDependenciesFds(d descriptor.Desc) []descriptor.Desc { + deps := d.GetDependencies() + if len(deps) == 0 { + return nil + } + + var allDeps []descriptor.Desc + allDeps = append(allDeps, deps...) + for _, dep := range deps { + allDeps = append(allDeps, allDependenciesFds(dep)...) + } + return allDeps +} diff --git a/util/apidocs/swagger/gen.go b/util/apidocs/swagger/gen.go new file mode 100644 index 0000000..691071b --- /dev/null +++ b/util/apidocs/swagger/gen.go @@ -0,0 +1,19 @@ +// Package swagger provides the ability to manipulate swagger documentation. +package swagger + +import ( + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs" +) + +// GenSwagger provides an external structure used to generate swagger JSON. +func GenSwagger(fd *descriptor.FileDescriptor, option *params.Option) error { + // Assemble the entire Swagger JSON information. + swaggerJSON, err := apidocs.NewSwagger(fd, option) + if err != nil { + return err + } + + return apidocs.WriteJSON(option.SwaggerOut, swaggerJSON) +} diff --git a/util/apidocs/swagger/gen_test.go b/util/apidocs/swagger/gen_test.go new file mode 100644 index 0000000..e45b0e3 --- /dev/null +++ b/util/apidocs/swagger/gen_test.go @@ -0,0 +1,66 @@ +package swagger + +import ( + "fmt" + "testing" + + "github.com/agiledragon/gomonkey" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/util/apidocs" +) + +func TestGenSwagger(t *testing.T) { + type args struct { + fd *descriptor.FileDescriptor + option *params.Option + } + tests := []struct { + name string + args args + wantErr bool + newErr error + }{ + { + name: "case1: new err", + args: args{ + fd: &descriptor.FileDescriptor{}, + option: ¶ms.Option{}, + }, + wantErr: true, + newErr: fmt.Errorf("err"), + }, + { + name: "case1: without err", + args: args{ + fd: &descriptor.FileDescriptor{}, + option: ¶ms.Option{}, + }, + wantErr: false, + newErr: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + p := gomonkey.ApplyFunc( + apidocs.NewSwagger, + func(fd *descriptor.FileDescriptor, option *params.Option) (*apidocs.SwaggerJSON, error) { + return &apidocs.SwaggerJSON{}, tt.newErr + }, + ).ApplyFunc( + apidocs.WriteJSON, + func(file string, data interface{}) error { + return nil + }, + ) + + defer p.Reset() + + if err := GenSwagger(tt.args.fd, tt.args.option); (err != nil) != tt.wantErr { + t.Errorf("GenSwagger() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/util/apidocs/swagger_test.go b/util/apidocs/swagger_test.go new file mode 100644 index 0000000..54358f7 --- /dev/null +++ b/util/apidocs/swagger_test.go @@ -0,0 +1,231 @@ +package apidocs + +import ( + "encoding/json" + "fmt" + "os" + + "reflect" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/jhump/protoreflect/desc" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" + "trpc.group/trpc-go/trpc-cmdline/params" + "trpc.group/trpc-go/trpc-cmdline/parser" + "trpc.group/trpc-go/trpc-cmdline/util/paths" +) + +func TestNewSwagger(t *testing.T) { + type args struct { + fd *descriptor.FileDescriptor + option *params.Option + } + tests := []struct { + name string + args args + want *SwaggerJSON + wantErr bool + genSwaggerInfoErr error + }{ + { + name: "case1-genSwaggerInfo_error", + args: args{ + fd: &descriptor.FileDescriptor{ + FD: &descriptor.ProtoFileDescriptor{ + FD: &desc.FileDescriptor{}, + }, + }, + option: ¶ms.Option{}, + }, + want: nil, + wantErr: true, + genSwaggerInfoErr: fmt.Errorf("error"), + }, + { + name: "case1-fd_nil", + args: args{ + fd: &descriptor.FileDescriptor{}, + option: ¶ms.Option{}, + }, + want: nil, + wantErr: true, + }, + { + name: "case2-success", + args: args{ + fd: &descriptor.FileDescriptor{ + FD: &descriptor.ProtoFileDescriptor{ + FD: &desc.FileDescriptor{}, + }, + }, + option: ¶ms.Option{}, + }, + want: &SwaggerJSON{ + Swagger: "2.0", + Info: InfoStruct{}, + Consumes: []string{"application/json"}, + Produces: []string{"application/json"}, + Paths: Paths{ + Elements: map[string]Methods{}, + Rank: map[string]int{}, + }, + Definitions: map[string]ModelStruct{}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc( + NewInfo, + func(fd *descriptor.FileDescriptor) (InfoStruct, error) { + return InfoStruct{}, tt.genSwaggerInfoErr + }, + ) + + p.ApplyFunc( + NewDefinitions, + func(options *params.Option, fds ...descriptor.Desc) *Definitions { + return &Definitions{ + models: map[string]ModelStruct{}, + } + }, + ) + + p.ApplyFunc( + NewPaths, + func(fd *descriptor.FileDescriptor, option *params.Option, defs *Definitions) Paths { + return Paths{ + Elements: map[string]Methods{}, + Rank: map[string]int{}, + } + }, + ) + + defer p.Reset() + + got, err := NewSwagger(tt.args.fd, tt.args.option) + if (err != nil) != tt.wantErr { + t.Errorf("NewSwagger() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewSwagger() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNewSwagger_with_file(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + SwaggerOptJSONParam: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + swagger, err := NewSwagger(fd, option) + require.NoError(t, err) + + gotByte, err := json.MarshalIndent(swagger, "", " ") + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/swagger.json") + require.NoError(t, err) + + require.Equal(t, string(wantByte), string(gotByte)) +} + +func TestNewSwagger_OrderByPBName_with_file(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + SwaggerOptJSONParam: true, + OrderByPBName: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + swagger, err := NewSwagger(fd, option) + require.NoError(t, err) + + gotByte, err := json.MarshalIndent(swagger, "", " ") + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/swagger_order_by_pbname.json") + require.NoError(t, err) + + require.Equal(t, string(wantByte), string(gotByte)) +} + +func TestNewSwagger_Unmarshal_file(t *testing.T) { + option := ¶ms.Option{ + Protodirs: append([]string{ + ".", + "../../install", + "../../install/protos", + }, paths.ExpandTRPCSearch("../../install")...), + Protofile: "testcase/hello.proto", + ProtofileAbs: "testcase/hello.proto", + SwaggerOptJSONParam: true, + OrderByPBName: true, + } + + fd, err := parser.ParseProtoFile( + option.Protofile, + option.Protodirs, + parser.WithAliasOn(option.AliasOn), + parser.WithLanguage(option.Language), + parser.WithRPCOnly(option.RPCOnly), + ) + if err != nil { + t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) + t.FailNow() + } + + gotSwagger, err := NewSwagger(fd, option) + require.NoError(t, err) + + wantByte, err := os.ReadFile("testcase/swagger_order_by_pbname.json") + require.NoError(t, err) + + var wantSwagger = &SwaggerJSON{} + err = json.Unmarshal(wantByte, wantSwagger) + require.NoError(t, err) + + require.Equal(t, wantSwagger, gotSwagger) +} diff --git a/util/apidocs/testcase/hello.proto b/util/apidocs/testcase/hello.proto new file mode 100644 index 0000000..2a8edef --- /dev/null +++ b/util/apidocs/testcase/hello.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; + +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "trpc/api/annotations.proto"; + +service Hello { + // 导入用户 + rpc ImportMembers(ImportMembersReq) returns (ImportMembersReply) { + option (trpc.api.http) = { + post: "/v1/members/import" + body: "*" + + additional_bindings: { + post: "/v1/{domain.type}/members/import" + body: "*" + } + }; + } + + // 添加成员,支持批量添加 + rpc SearchMembers(SearchMembersReq) returns (SearchMembersReply) { + option (trpc.api.http) = { + get: "/v1/members" + + additional_bindings: { + get: "/v1/{domain.type=school}/members" + } + }; + } + + // 移除成员,支持批量移除 + rpc RemoveMembers(RemoveMembersReq) returns (RemoveMembersReply) { + option (trpc.api.http) = { + delete: "/v1/members" + }; + } +} + + +message Domain { + uint32 id = 1; + string type = 2; +} + +message ImportMembersReq { + Domain domain = 1; + string url = 2; +} + +message ImportMembersReply {} + +enum TYPE { + A = 0; + B = 1; +} + +message SearchMembersReq { + Domain domain = 1; + uint32 page = 2; + uint32 page_size = 3; + TYPE t =4; +} + +message SearchMembersReply { + message Member { + uint32 id = 1; + } + + uint32 total = 1; + repeated Member members = 2; +} + +message RemoveMembersReq { + repeated uint32 ids = 1; +} + +message RemoveMembersReply {} \ No newline at end of file diff --git a/util/apidocs/testcase/openapi.json b/util/apidocs/testcase/openapi.json new file mode 100644 index 0000000..2d35bae --- /dev/null +++ b/util/apidocs/testcase/openapi.json @@ -0,0 +1,507 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "hello", + "description": "The api document of hello.proto", + "version": "2.0" + }, + "paths": { + "/helloworld.Hello/ImportMembers": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "domain.type" + } + }, + { + "name": "url", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "url" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/RemoveMembers": { + "post": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "schema": { + "type": "array", + "title": "ids", + "items": { + "type": "integer", + "format": "uint32" + } + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/SearchMembers": { + "post": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "domain.type" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members": { + "delete": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers2", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "schema": { + "type": "array", + "title": "ids", + "items": { + "type": "integer", + "format": "uint32" + } + } + } + ], + "tags": [ + "hello.restful" + ] + }, + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers2", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "domain.type" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers2", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + }, + "/v1/school/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers3", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/{domain.type}/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers3", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.type", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "domain.type" + } + } + ], + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + } + }, + "components": { + "schemas": { + "helloworld.Domain": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + }, + "type": { + "title": "type", + "type": "string" + } + }, + "title": "helloworld.Domain", + "description": "Domain" + }, + "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155", + "description": "Domain" + }, + "helloworld.ImportMembersReply": { + "type": "object", + "title": "helloworld.ImportMembersReply", + "description": "ImportMembersReply" + }, + "helloworld.ImportMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq", + "description": "ImportMembersReq" + }, + "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155", + "description": "ImportMembersReq" + }, + "helloworld.RemoveMembersReply": { + "type": "object", + "title": "helloworld.RemoveMembersReply", + "description": "RemoveMembersReply" + }, + "helloworld.SearchMembersReply": { + "type": "object", + "properties": { + "members": { + "title": "members", + "type": "array", + "items": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply.Member" + } + }, + "total": { + "title": "total", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply", + "description": "SearchMembersReply" + }, + "helloworld.SearchMembersReply.Member": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply.Member", + "description": "Member" + } + } + } +} \ No newline at end of file diff --git a/util/apidocs/testcase/openapi_json_param.json b/util/apidocs/testcase/openapi_json_param.json new file mode 100644 index 0000000..329f00f --- /dev/null +++ b/util/apidocs/testcase/openapi_json_param.json @@ -0,0 +1,491 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "hello", + "description": "The api document of hello.proto", + "version": "2.0" + }, + "paths": { + "/helloworld.Hello/ImportMembers": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/RemoveMembers": { + "post": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/SearchMembers": { + "post": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members": { + "delete": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers2", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "schema": { + "type": "array", + "title": "ids", + "items": { + "type": "integer", + "format": "uint32" + } + } + } + ], + "tags": [ + "hello.restful" + ] + }, + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers2", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "domain.type" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers2", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + }, + "/v1/school/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers3", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/{domain.type}/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers3", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.type", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "domain.type" + } + } + ], + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + } + }, + "components": { + "schemas": { + "helloworld.Domain": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + }, + "type": { + "title": "type", + "type": "string" + } + }, + "title": "helloworld.Domain", + "description": "Domain" + }, + "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155", + "description": "Domain" + }, + "helloworld.ImportMembersReply": { + "type": "object", + "title": "helloworld.ImportMembersReply", + "description": "ImportMembersReply" + }, + "helloworld.ImportMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq", + "description": "ImportMembersReq" + }, + "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155", + "description": "ImportMembersReq" + }, + "helloworld.RemoveMembersReply": { + "type": "object", + "title": "helloworld.RemoveMembersReply", + "description": "RemoveMembersReply" + }, + "helloworld.RemoveMembersReq": { + "type": "object", + "properties": { + "ids": { + "title": "ids", + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + }, + "title": "helloworld.RemoveMembersReq", + "description": "RemoveMembersReq" + }, + "helloworld.SearchMembersReply": { + "type": "object", + "properties": { + "members": { + "title": "members", + "type": "array", + "items": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply.Member" + } + }, + "total": { + "title": "total", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply", + "description": "SearchMembersReply" + }, + "helloworld.SearchMembersReply.Member": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply.Member", + "description": "Member" + }, + "helloworld.SearchMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain" + }, + "page": { + "title": "page", + "type": "integer", + "format": "uint32" + }, + "page_size": { + "title": "page_size", + "type": "integer", + "format": "uint32" + }, + "t": { + "title": "t", + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + }, + "title": "helloworld.SearchMembersReq", + "description": "SearchMembersReq" + } + } + } +} \ No newline at end of file diff --git a/util/apidocs/testcase/openapi_order_by_pbname.json b/util/apidocs/testcase/openapi_order_by_pbname.json new file mode 100644 index 0000000..b7b6e47 --- /dev/null +++ b/util/apidocs/testcase/openapi_order_by_pbname.json @@ -0,0 +1,491 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "hello", + "description": "The api document of hello.proto", + "version": "2.0" + }, + "paths": { + "/helloworld.Hello/ImportMembers": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers2", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + }, + "/v1/{domain.type}/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers3", + "responses": { + "200": { + "description": "ImportMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.type", + "in": "path", + "required": true, + "schema": { + "type": "string", + "title": "domain.type" + } + } + ], + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155" + } + } + } + }, + "tags": [ + "hello.restful" + ] + } + }, + "/helloworld.Hello/SearchMembers": { + "post": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers2", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "title": "domain.type" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + }, + "delete": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "schema": { + "type": "array", + "title": "ids", + "items": { + "type": "integer", + "format": "uint32" + } + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/school/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers3", + "responses": { + "200": { + "description": "SearchMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply" + } + } + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "domain.id" + } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page" + } + }, + { + "name": "page_size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "title": "page_size" + } + }, + { + "name": "t", + "in": "query", + "required": false, + "description": " * 0 - A - \n * 1 - B - \n", + "schema": { + "type": "integer", + "title": "t", + "description": " * 0 - A - \n * 1 - B - \n" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/helloworld.Hello/RemoveMembers": { + "post": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers2", + "responses": { + "200": { + "description": "RemoveMembersReply", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReply" + } + } + } + } + }, + "requestBody": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/helloworld.RemoveMembersReq" + } + } + } + }, + "tags": [ + "hello.trpc" + ] + } + } + }, + "components": { + "schemas": { + "helloworld.Domain": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + }, + "type": { + "title": "type", + "type": "string" + } + }, + "title": "helloworld.Domain", + "description": "Domain" + }, + "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155", + "description": "Domain" + }, + "helloworld.ImportMembersReply": { + "type": "object", + "title": "helloworld.ImportMembersReply", + "description": "ImportMembersReply" + }, + "helloworld.ImportMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq", + "description": "ImportMembersReq" + }, + "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155", + "description": "ImportMembersReq" + }, + "helloworld.RemoveMembersReply": { + "type": "object", + "title": "helloworld.RemoveMembersReply", + "description": "RemoveMembersReply" + }, + "helloworld.RemoveMembersReq": { + "type": "object", + "properties": { + "ids": { + "title": "ids", + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + }, + "title": "helloworld.RemoveMembersReq", + "description": "RemoveMembersReq" + }, + "helloworld.SearchMembersReply": { + "type": "object", + "properties": { + "total": { + "title": "total", + "type": "integer", + "format": "uint32" + }, + "members": { + "title": "members", + "type": "array", + "items": { + "$ref": "#/components/schemas/helloworld.SearchMembersReply.Member" + } + } + }, + "title": "helloworld.SearchMembersReply", + "description": "SearchMembersReply" + }, + "helloworld.SearchMembersReply.Member": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply.Member", + "description": "Member" + }, + "helloworld.SearchMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/components/schemas/helloworld.Domain" + }, + "page": { + "title": "page", + "type": "integer", + "format": "uint32" + }, + "page_size": { + "title": "page_size", + "type": "integer", + "format": "uint32" + }, + "t": { + "title": "t", + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + }, + "title": "helloworld.SearchMembersReq", + "description": "SearchMembersReq" + } + } + } +} \ No newline at end of file diff --git a/util/apidocs/testcase/swagger.json b/util/apidocs/testcase/swagger.json new file mode 100644 index 0000000..5e76d4d --- /dev/null +++ b/util/apidocs/testcase/swagger.json @@ -0,0 +1,444 @@ +{ + "swagger": "2.0", + "info": { + "title": "hello", + "description": "The api document of hello.proto", + "version": "2.0" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/helloworld.Hello/ImportMembers": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/RemoveMembers": { + "post": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers", + "responses": { + "200": { + "description": "RemoveMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/helloworld.Hello/SearchMembers": { + "post": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members": { + "delete": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers2", + "responses": { + "200": { + "description": "RemoveMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReply" + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + ], + "tags": [ + "hello.restful" + ] + }, + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers2", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page_size", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "t", + "in": "query", + "required": false, + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers2", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/school/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers3", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page_size", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "t", + "in": "query", + "required": false, + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/{domain.type}/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers3", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.type", + "in": "path", + "required": true, + "type": "string", + "default": "" + }, + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155" + } + } + ], + "tags": [ + "hello.restful" + ] + } + } + }, + "definitions": { + "helloworld.Domain": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + }, + "type": { + "title": "type", + "type": "string" + } + }, + "title": "helloworld.Domain", + "description": "Domain" + }, + "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155", + "description": "Domain" + }, + "helloworld.ImportMembersReply": { + "type": "object", + "title": "helloworld.ImportMembersReply", + "description": "ImportMembersReply" + }, + "helloworld.ImportMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq", + "description": "ImportMembersReq" + }, + "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155", + "description": "ImportMembersReq" + }, + "helloworld.RemoveMembersReply": { + "type": "object", + "title": "helloworld.RemoveMembersReply", + "description": "RemoveMembersReply" + }, + "helloworld.RemoveMembersReq": { + "type": "object", + "properties": { + "ids": { + "title": "ids", + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + }, + "title": "helloworld.RemoveMembersReq", + "description": "RemoveMembersReq" + }, + "helloworld.SearchMembersReply": { + "type": "object", + "properties": { + "members": { + "title": "members", + "type": "array", + "items": { + "$ref": "#/definitions/helloworld.SearchMembersReply.Member" + } + }, + "total": { + "title": "total", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply", + "description": "SearchMembersReply" + }, + "helloworld.SearchMembersReply.Member": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply.Member", + "description": "Member" + }, + "helloworld.SearchMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain" + }, + "page": { + "title": "page", + "type": "integer", + "format": "uint32" + }, + "page_size": { + "title": "page_size", + "type": "integer", + "format": "uint32" + }, + "t": { + "title": "t", + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + }, + "title": "helloworld.SearchMembersReq", + "description": "SearchMembersReq" + } + } +} \ No newline at end of file diff --git a/util/apidocs/testcase/swagger_order_by_pbname.json b/util/apidocs/testcase/swagger_order_by_pbname.json new file mode 100644 index 0000000..e6c3a10 --- /dev/null +++ b/util/apidocs/testcase/swagger_order_by_pbname.json @@ -0,0 +1,444 @@ +{ + "swagger": "2.0", + "info": { + "title": "hello", + "description": "The api document of hello.proto", + "version": "2.0" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/helloworld.Hello/ImportMembers": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers2", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/{domain.type}/members/import": { + "post": { + "summary": "导入用户", + "operationId": "ImportMembers3", + "responses": { + "200": { + "description": "ImportMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.type", + "in": "path", + "required": true, + "type": "string", + "default": "" + }, + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/helloworld.Hello/SearchMembers": { + "post": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + }, + "/v1/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers2", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "domain.type", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page_size", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "t", + "in": "query", + "required": false, + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + ], + "tags": [ + "hello.restful" + ] + }, + "delete": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers", + "responses": { + "200": { + "description": "RemoveMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReply" + } + } + }, + "parameters": [ + { + "name": "ids", + "in": "query", + "required": false, + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/v1/school/members": { + "get": { + "summary": "添加成员,支持批量添加", + "operationId": "SearchMembers3", + "responses": { + "200": { + "description": "SearchMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.SearchMembersReply" + } + } + }, + "parameters": [ + { + "name": "domain.id", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "page_size", + "in": "query", + "required": false, + "type": "integer", + "format": "uint32" + }, + { + "name": "t", + "in": "query", + "required": false, + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + ], + "tags": [ + "hello.restful" + ] + } + }, + "/helloworld.Hello/RemoveMembers": { + "post": { + "summary": "移除成员,支持批量移除", + "operationId": "RemoveMembers2", + "responses": { + "200": { + "description": "RemoveMembersReply", + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReply" + } + } + }, + "parameters": [ + { + "name": "requestBody", + "in": "body", + "required": false, + "schema": { + "$ref": "#/definitions/helloworld.RemoveMembersReq" + } + } + ], + "tags": [ + "hello.trpc" + ] + } + } + }, + "definitions": { + "helloworld.Domain": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + }, + "type": { + "title": "type", + "type": "string" + } + }, + "title": "helloworld.Domain", + "description": "Domain" + }, + "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155", + "description": "Domain" + }, + "helloworld.ImportMembersReply": { + "type": "object", + "title": "helloworld.ImportMembersReply", + "description": "ImportMembersReply" + }, + "helloworld.ImportMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq", + "description": "ImportMembersReq" + }, + "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain.aa6718f0a7c001e99386d62d6a0da155" + }, + "url": { + "title": "url", + "type": "string" + } + }, + "title": "helloworld.ImportMembersReq.aa6718f0a7c001e99386d62d6a0da155", + "description": "ImportMembersReq" + }, + "helloworld.RemoveMembersReply": { + "type": "object", + "title": "helloworld.RemoveMembersReply", + "description": "RemoveMembersReply" + }, + "helloworld.RemoveMembersReq": { + "type": "object", + "properties": { + "ids": { + "title": "ids", + "type": "array", + "format": "uint32", + "items": { + "type": "integer", + "format": "uint32" + } + } + }, + "title": "helloworld.RemoveMembersReq", + "description": "RemoveMembersReq" + }, + "helloworld.SearchMembersReply": { + "type": "object", + "properties": { + "total": { + "title": "total", + "type": "integer", + "format": "uint32" + }, + "members": { + "title": "members", + "type": "array", + "items": { + "$ref": "#/definitions/helloworld.SearchMembersReply.Member" + } + } + }, + "title": "helloworld.SearchMembersReply", + "description": "SearchMembersReply" + }, + "helloworld.SearchMembersReply.Member": { + "type": "object", + "properties": { + "id": { + "title": "id", + "type": "integer", + "format": "uint32" + } + }, + "title": "helloworld.SearchMembersReply.Member", + "description": "Member" + }, + "helloworld.SearchMembersReq": { + "type": "object", + "properties": { + "domain": { + "title": "domain", + "$ref": "#/definitions/helloworld.Domain" + }, + "page": { + "title": "page", + "type": "integer", + "format": "uint32" + }, + "page_size": { + "title": "page_size", + "type": "integer", + "format": "uint32" + }, + "t": { + "title": "t", + "type": "integer", + "format": "int32", + "description": " * 0 - A - \n * 1 - B - \n", + "enum": [ + 0, + 1 + ] + } + }, + "title": "helloworld.SearchMembersReq", + "description": "SearchMembersReq" + } + } +} \ No newline at end of file diff --git a/util/apidocs/x/types.go b/util/apidocs/x/types.go new file mode 100644 index 0000000..ee21393 --- /dev/null +++ b/util/apidocs/x/types.go @@ -0,0 +1,70 @@ +// Package x provides common utilities for documentation operations. +package x + +import protobuf "google.golang.org/protobuf/types/descriptorpb" + +// FieldDescriptorProtoTypeFormats is used to convert field type definitions +// from the protobuf library to the openapi data format map. +var FieldDescriptorProtoTypeFormats = map[protobuf.FieldDescriptorProto_Type]string{ + protobuf.FieldDescriptorProto_TYPE_DOUBLE: "double", + protobuf.FieldDescriptorProto_TYPE_FLOAT: "float", + protobuf.FieldDescriptorProto_TYPE_INT64: "int64", + protobuf.FieldDescriptorProto_TYPE_UINT64: "uint64", + protobuf.FieldDescriptorProto_TYPE_INT32: "int32", + protobuf.FieldDescriptorProto_TYPE_FIXED64: "fixed64", + protobuf.FieldDescriptorProto_TYPE_FIXED32: "fixed32", + // Refer to https://swagger.io/specification, boolean type doesn't need to set format. + protobuf.FieldDescriptorProto_TYPE_BOOL: "", + // Refer to https://swagger.io/specification, string type doesn't need to set format. + protobuf.FieldDescriptorProto_TYPE_STRING: "", + protobuf.FieldDescriptorProto_TYPE_GROUP: "group", + protobuf.FieldDescriptorProto_TYPE_MESSAGE: "message", + protobuf.FieldDescriptorProto_TYPE_BYTES: "bytes", + protobuf.FieldDescriptorProto_TYPE_UINT32: "uint32", + protobuf.FieldDescriptorProto_TYPE_ENUM: "int32", + protobuf.FieldDescriptorProto_TYPE_SFIXED32: "sfixed32", + protobuf.FieldDescriptorProto_TYPE_SFIXED64: "sfixed64", + protobuf.FieldDescriptorProto_TYPE_SINT32: "sint32", + protobuf.FieldDescriptorProto_TYPE_SINT64: "sint64", +} + +// FieldDescriptorProtoTypes is used to convert field types defined in protobuf library to openapi data type map table. +// Since trpc uses jsonpb as the default encoding and decoding method, +// according to the proto specification, int64, uint64, and fixed64 will be serialized as strings. +var FieldDescriptorProtoTypes = map[protobuf.FieldDescriptorProto_Type]string{ + protobuf.FieldDescriptorProto_TYPE_BOOL: "boolean", + protobuf.FieldDescriptorProto_TYPE_DOUBLE: "number", + protobuf.FieldDescriptorProto_TYPE_FLOAT: "number", + protobuf.FieldDescriptorProto_TYPE_INT64: "string", + protobuf.FieldDescriptorProto_TYPE_UINT64: "string", + protobuf.FieldDescriptorProto_TYPE_INT32: "integer", + protobuf.FieldDescriptorProto_TYPE_FIXED64: "string", + protobuf.FieldDescriptorProto_TYPE_FIXED32: "integer", + protobuf.FieldDescriptorProto_TYPE_UINT32: "integer", + protobuf.FieldDescriptorProto_TYPE_SFIXED32: "integer", + protobuf.FieldDescriptorProto_TYPE_SFIXED64: "integer", + protobuf.FieldDescriptorProto_TYPE_SINT32: "integer", + protobuf.FieldDescriptorProto_TYPE_SINT64: "integer", + protobuf.FieldDescriptorProto_TYPE_ENUM: "integer", + protobuf.FieldDescriptorProto_TYPE_STRING: "string", + protobuf.FieldDescriptorProto_TYPE_BYTES: "string", + protobuf.FieldDescriptorProto_TYPE_MESSAGE: "object", +} + +// GetFormatStr returns the specific format of a field based on its protobuf type. +func GetFormatStr(t protobuf.FieldDescriptorProto_Type) string { + if val, ok := FieldDescriptorProtoTypeFormats[t]; ok { + return val + } + + return "string" +} + +// GetTypeStr returns the specific field type according to the protobuf type. +func GetTypeStr(t protobuf.FieldDescriptorProto_Type) string { + if val, ok := FieldDescriptorProtoTypes[t]; ok { + return val + } + + return "string" +} diff --git a/util/apidocs/x/types_test.go b/util/apidocs/x/types_test.go new file mode 100644 index 0000000..11fbd0c --- /dev/null +++ b/util/apidocs/x/types_test.go @@ -0,0 +1,79 @@ +package x + +import ( + "testing" + + protobuf "google.golang.org/protobuf/types/descriptorpb" +) + +func TestGetFormatStr(t *testing.T) { + tests := []struct { + name string + pType protobuf.FieldDescriptorProto_Type + want string + }{ + {"DOUBLE", protobuf.FieldDescriptorProto_TYPE_DOUBLE, "double"}, + {"FLOAT", protobuf.FieldDescriptorProto_TYPE_FLOAT, "float"}, + {"INT64", protobuf.FieldDescriptorProto_TYPE_INT64, "int64"}, + {"UINT64", protobuf.FieldDescriptorProto_TYPE_UINT64, "uint64"}, + {"INT32", protobuf.FieldDescriptorProto_TYPE_INT32, "int32"}, + {"FIXED64", protobuf.FieldDescriptorProto_TYPE_FIXED64, "fixed64"}, + {"FIXED32", protobuf.FieldDescriptorProto_TYPE_FIXED32, "fixed32"}, + {"BOOL", protobuf.FieldDescriptorProto_TYPE_BOOL, ""}, + {"STRING", protobuf.FieldDescriptorProto_TYPE_STRING, ""}, + {"GROUP", protobuf.FieldDescriptorProto_TYPE_GROUP, "group"}, + {"MESSAGE", protobuf.FieldDescriptorProto_TYPE_MESSAGE, "message"}, + {"BYTES", protobuf.FieldDescriptorProto_TYPE_BYTES, "bytes"}, + {"UINT32", protobuf.FieldDescriptorProto_TYPE_UINT32, "uint32"}, + // Enum type format should be set to int32 (with type as integer) + {"ENUM", protobuf.FieldDescriptorProto_TYPE_ENUM, "int32"}, + {"SFIXED32", protobuf.FieldDescriptorProto_TYPE_SFIXED32, "sfixed32"}, + {"SFIXED64", protobuf.FieldDescriptorProto_TYPE_SFIXED64, "sfixed64"}, + {"SINT32", protobuf.FieldDescriptorProto_TYPE_SINT32, "sint32"}, + {"SINT64", protobuf.FieldDescriptorProto_TYPE_SINT64, "sint64"}, + {"other set to string", 19, "string"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetFormatStr(tt.pType); got != tt.want { + t.Errorf("GetFormatStr() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestGetTypeStr(t *testing.T) { + tests := []struct { + name string + pType protobuf.FieldDescriptorProto_Type + want string + }{ + {"bool", protobuf.FieldDescriptorProto_TYPE_BOOL, "boolean"}, + {"double", protobuf.FieldDescriptorProto_TYPE_DOUBLE, "number"}, + {"float", protobuf.FieldDescriptorProto_TYPE_FLOAT, "number"}, + {"int64", protobuf.FieldDescriptorProto_TYPE_INT64, "string"}, + {"int32", protobuf.FieldDescriptorProto_TYPE_INT32, "integer"}, + {"uint64", protobuf.FieldDescriptorProto_TYPE_UINT64, "string"}, + {"uint32", protobuf.FieldDescriptorProto_TYPE_UINT32, "integer"}, + {"fixed64", protobuf.FieldDescriptorProto_TYPE_FIXED64, "string"}, + {"fixed32", protobuf.FieldDescriptorProto_TYPE_FIXED32, "integer"}, + {"sfixed64", protobuf.FieldDescriptorProto_TYPE_SFIXED64, "integer"}, + {"sfixed32", protobuf.FieldDescriptorProto_TYPE_SFIXED32, "integer"}, + {"sint64", protobuf.FieldDescriptorProto_TYPE_SINT64, "integer"}, + {"sint32", protobuf.FieldDescriptorProto_TYPE_SINT32, "integer"}, + // Enum type should be set to integer. + {"enum", protobuf.FieldDescriptorProto_TYPE_ENUM, "integer"}, + {"string", protobuf.FieldDescriptorProto_TYPE_STRING, "string"}, + {"bytes", protobuf.FieldDescriptorProto_TYPE_BYTES, "string"}, + {"message", protobuf.FieldDescriptorProto_TYPE_MESSAGE, "object"}, + {"other set to string", 19, "string"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetTypeStr(tt.pType); got != tt.want { + t.Errorf("GetTypeStr() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/util/browser/browser.go b/util/browser/browser.go new file mode 100644 index 0000000..cfc2d58 --- /dev/null +++ b/util/browser/browser.go @@ -0,0 +1,63 @@ +// Package browser provides utilities for interacting with users' browsers. +package browser + +import ( + "os" + "os/exec" + "runtime" + "time" +) + +// Commands returns a list of possible commands to use to open a url. +func Commands() [][]string { + var cmds [][]string + if exe := os.Getenv("BROWSER"); exe != "" { + cmds = append(cmds, []string{exe}) + } + switch runtime.GOOS { + case "darwin": + cmds = append(cmds, []string{"/usr/bin/open"}) + case "windows": + cmds = append(cmds, []string{"cmd", "/c", "start"}) + default: + if os.Getenv("DISPLAY") != "" { + // xdg-open is only for use in a desktop environment. + cmds = append(cmds, []string{"xdg-open"}) + } + } + cmds = append(cmds, + []string{"chrome"}, + []string{"google-chrome"}, + []string{"chromium"}, + []string{"firefox"}, + ) + return cmds +} + +// Open tries to open url in a browser and reports whether it succeeded. +func Open(url string) bool { + for _, args := range Commands() { + cmd := exec.Command(args[0], append(args[1:], url)...) + if cmd.Start() == nil && appearsSuccessful(cmd, 3*time.Second) { + return true + } + } + return false +} + +// appearsSuccessful reports whether the command appears to have run successfully. +// If the command runs longer than the timeout, it's deemed successful. +// If the command runs within the timeout, it's deemed successful if it exited cleanly. +func appearsSuccessful(cmd *exec.Cmd, timeout time.Duration) bool { + errc := make(chan error, 1) + go func() { + errc <- cmd.Wait() + }() + + select { + case <-time.After(timeout): + return true + case err := <-errc: + return err == nil + } +} diff --git a/util/fb/fb_test.go b/util/fb/fb_test.go new file mode 100644 index 0000000..fb52f5a --- /dev/null +++ b/util/fb/fb_test.go @@ -0,0 +1,125 @@ +package fb + +import ( + "fmt" + "os" + "path" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestFlatcNormal(t *testing.T) { + dir := "./testcase/normal" + file := path.Join(dir, "hello.fbs") + fileAbs, err := filepath.Abs(file) + require.Nil(t, err) + out := filepath.Join(os.TempDir(), "flatc_generated") + os.RemoveAll(out) + fb2ImportPath := map[string]string{ + "hello.fbs": "trpc.group/examples/hello", + } + pkg2ImportPath := map[string]string{ + "hello": "trpc.group/examples/hello", + } + opts := []Option{ + WithFbsDirs([]string{dir}), + WithFbsfile(fileAbs), + WithLanguage("go"), + WithPackagePath("hello"), + WithOutputdir(out), + WithFb2ImportPath(fb2ImportPath), + WithPkg2ImportPath(pkg2ImportPath), + } + f := NewFbs(opts...) + err = f.Flatc() + require.Nil(t, err, fmt.Sprintf("err: %+v", err)) +} + +func TestFlatcError(t *testing.T) { + dir := "./testcase/error" + file := path.Join(dir, "hello.fbs") + fileAbs, err := filepath.Abs(file) + require.Nil(t, err) + out := filepath.Join(os.TempDir(), "flatc_generated") + os.RemoveAll(out) + fb2ImportPath := map[string]string{ + "hello.fbs": "trpc.group/examples/hello", + } + pkg2ImportPath := map[string]string{ + "hello": "trpc.group/examples/hello", + } + opts := []Option{ + WithFbsDirs([]string{dir}), + WithFbsfile(fileAbs), + WithLanguage("go"), + WithPackagePath("hello"), + WithOutputdir(out), + WithFb2ImportPath(fb2ImportPath), + WithPkg2ImportPath(pkg2ImportPath), + } + f := NewFbs(opts...) + err = f.Flatc() + require.NotNil(t, err) +} + +func TestFlatcMultiFBDiffGopkg(t *testing.T) { + dir := "./testcase/multi-fb-diff-gopkg" + file := path.Join(dir, "fbsread.fbs") + fileAbs, err := filepath.Abs(file) + require.Nil(t, err) + out := filepath.Join(os.TempDir(), "flatc_generated") + os.RemoveAll(out) + fb2ImportPath := map[string]string{ + "fbsread.fbs": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsread", + "circlesearch/common/feedcloud/fbsmeta.fbs": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsmeta", + "circlesearch/common/feedcloud/common.fbs": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_common", + } + pkg2ImportPath := map[string]string{ + "trpc.circlesearch.common_feedcloud_fbsread": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsread", + "trpc.circlesearch.common_feedcloud_fbsmeta": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsmeta", + "trpc.circlesearch.common_feedcloud_common": "trpc.group/trpcprotocol/circlesearch/common_feedcloud_common", + } + opts := []Option{ + WithFbsDirs([]string{dir}), + WithFbsfile(fileAbs), + WithLanguage("go"), + WithPackagePath("hello"), + WithOutputdir(out), + WithFb2ImportPath(fb2ImportPath), + WithPkg2ImportPath(pkg2ImportPath), + } + f := NewFbs(opts...) + err = f.Flatc() + require.Nil(t, err, fmt.Sprintf("err: %+v", err)) +} + +func Test_replacePkgNameInFiles(t *testing.T) { + type args struct { + files []string + originImport string + importPath string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "file not exists", + args: args{ + files: []string{"a_file_that_doesnot_exist.fbs"}, + originImport: "nana", + importPath: "lala", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := replacePkgNameInFiles(tt.args.files, tt.args.originImport, tt.args.importPath); (err != nil) != tt.wantErr { + t.Errorf("replacePkgNameInFiles got error %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/util/fb/fbs.go b/util/fb/fbs.go new file mode 100644 index 0000000..f845559 --- /dev/null +++ b/util/fb/fbs.go @@ -0,0 +1,135 @@ +// Package fb encapsulates functions related to .fbs files. +package fb + +import ( + "fmt" + "os" + + "os/exec" + "path" + "path/filepath" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// Fbs stores a set of parameters that may be used when invoking flatc. +type Fbs struct { + // language indicates the language information such as Go, etc. + language string + + // The packagePath parameter only contains the last part of the namespace or go_package, for example, + // if the namespace is trpc.testapp.testserver, then the packagePath is testserver. + // This parameter is passed directly to flatc's --go-namespace option to ensure that the beginning of the + // generated file package is correct. + packagePath string + + // fb2ImportPath maps flatbuffers file name to import path + // for example "./file1.fbs" => "trpc.group/testapp/testserver1" + fb2ImportPath map[string]string + + // Maps package names to their corresponding import paths. + // For example, "trpc.testapp.testserver1" => "trpc.group/testapp/testserver1". + pkg2ImportPath map[string]string + + args struct { + // fbsfile represents the name of the flatbuffers file. + // This field is initially passed in by the user from the trpc command line and may contain part of the path + // information, such as "./test/file1.fbs". + fbsfile string + // includePaths indicates the paths to search for include files. + includePaths []string + // outDir represents the output directory. + outDir string + } +} + +// NewFbs creates a new Fbs struct based on the input parameter list. +func NewFbs(opts ...Option) *Fbs { + f := &Fbs{} + for _, opt := range opts { + opt(f) + } + // In the output path, the packagePath needs to be removed, because the packagePath is specified as --go-namespace. + // In this way, flatc will create the packagePath folder in outDir when generating stub code. + f.args.outDir = strings.TrimSuffix(f.args.outDir, fmt.Sprintf("%c%s", filepath.Separator, f.packagePath)) + return f +} + +// Flatc executes flatc to generate stub code for each type defined in the .fbs file. +func (f *Fbs) Flatc() error { + var args []string + for _, dir := range f.args.includePaths { + args = append(args, "-I") + args = append(args, dir) + } + + args = append(args, fmt.Sprintf("--%v", f.language)) // Indicates the language of the generated code passed to flatc. + + // Specify the namespace explicitly + // Ensure that packagePath only contains the last segment, otherwise flatc will generate nested paths. + args = append(args, "--go-namespace", f.packagePath) + + // Specifies the path where the generated files will be placed. + args = append(args, "-o", f.args.outDir) + + // Specifies the flatbuffers file to process. + args = append(args, f.args.fbsfile) + + cmd := exec.Command("flatc", args...) + s := strings.Join(cmd.Args, " ") + + if buf, err := cmd.CombinedOutput(); err != nil { + log.Error("run command: %v, err: %v, msg: %s", s, err, string(buf)) + return err + } + log.Debug("run command: %v, success", s) + + // Replace incorrect import path. + f.replacePkgName() + return nil +} + +// For each included package, replace the incorrect import path generated by flatc with the correct one. +// For example, if file1.fbs includes a file and references a type in that file +// that is not in the same go package as file1.fbs, +// when flatc generates the stub code for file1.fbs, +// it will import the package using an import path that replaces dots in its namespace with slashes, +// which is not the format it should have (e.g. "trpc.group/.."). +// Therefore, at this step, +// the generated import path needs to be replaced with the content of the go_package declared in the included file. +func (f *Fbs) replacePkgName() { + curOutDir := path.Join(f.args.outDir, f.packagePath) + for namespace, importPath := range f.pkg2ImportPath { + originImportPath := strings.Replace(namespace, ".", "/", -1) + s := "\"" + originImportPath + "\"" + files, err := filepath.Glob(path.Join(curOutDir, "*.go")) + if err != nil { + log.Debug("find .go files error: %v ", err) + continue + } + _ = replacePkgNameInFiles(files, s, importPath) + } +} + +// replacePkgNameInFiles replaces the occurrences of originImport with importPath in the given list of files. +func replacePkgNameInFiles(files []string, originImport, importPath string) error { + for _, file := range files { + input, err := os.ReadFile(file) + if err != nil { + log.Debug("read file %v error: %v ", file, err) + continue + } + lines := strings.Split(string(input), "\n") + for i := range lines { + lines[i] = strings.Replace(lines[i], originImport, "\""+importPath+"\"", -1) + } + output := strings.Join(lines, "\n") + err = os.WriteFile(file, []byte(output), 0644) + if err != nil { + log.Debug("write file %v error: %v ", file, err) + continue + } + } + return nil +} diff --git a/util/fb/option.go b/util/fb/option.go new file mode 100644 index 0000000..fe1a89f --- /dev/null +++ b/util/fb/option.go @@ -0,0 +1,59 @@ +package fb + +// The Option type implements the functional options pattern. +type Option func(*Fbs) + +// WithFbsDirs sets the fbsdirs parameter. +func WithFbsDirs(dirs []string) Option { + return func(o *Fbs) { + o.args.includePaths = dirs + } +} + +// WithFbsfile sets the fbsfile parameter. +func WithFbsfile(file string) Option { + return func(o *Fbs) { + o.args.fbsfile = file + } +} + +// WithLanguage sets the language parameter. +func WithLanguage(language string) Option { + return func(o *Fbs) { + o.language = language + } +} + +// WithPackagePath sets the packagePath parameter. +func WithPackagePath(packagePath string) Option { + return func(o *Fbs) { + o.packagePath = packagePath + } +} + +// WithOutputdir sets the outputdir parameter. +func WithOutputdir(dir string) Option { + return func(o *Fbs) { + o.args.outDir = dir + } +} + +// WithFb2ImportPath sets the mapping relationship between the flatbuffers file names and the import paths. +// For example, +// "./file1.fbs" => "trpc.group/testapp/testserver1" +// "./file2.fbs" => "trpc.group/testapp/testserver2" +func WithFb2ImportPath(m map[string]string) Option { + return func(o *Fbs) { + o.fb2ImportPath = m + } +} + +// WithPkg2ImportPath sets the mapping between package name and import path +// For example: +// "trpc.testapp.testserver1" => "trpc.group/testapp/testserver1" +// "trpc.testapp.testserver2" => "trpc.group/testapp/testserver2" +func WithPkg2ImportPath(m map[string]string) Option { + return func(o *Fbs) { + o.pkg2ImportPath = m + } +} diff --git a/util/fb/testcase/error/hello.fbs b/util/fb/testcase/error/hello.fbs new file mode 100755 index 0000000..5292603 --- /dev/null +++ b/util/fb/testcase/error/hello.fbs @@ -0,0 +1,9 @@ +include "message.fbs"; +namespace hello; + +attribute "go_package=trpc.group/examples/hello"; + + +rpc_service hello_svr { + Hello(HelloReq):HelloRsp; +} \ No newline at end of file diff --git a/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs b/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs new file mode 100755 index 0000000..59d1d7b --- /dev/null +++ b/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/common.fbs @@ -0,0 +1,29 @@ +// namespace trpc.circlesearch.common; +namespace trpc.circlesearch.common_feedcloud_common; +// namespace trpc.group.trpcprotocol.circlesearch.common_feedcloud_common; +// namespace circlesearch.common_feedcloud_common; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_common"; + +// mapitem +table Entry { + key:string; + value:string; +} + +table BytesEntry { + key:string; + value:[ubyte]; +} + +table Result { + retCode:int; + msg:string; +} + +// 通用扩展字段,可以带mapkv和querystring +table StCommonExt { + mapInfo:[circlesearch.common_feedcloud_common.Entry]; + attachInfo:string; +} + diff --git a/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs b/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs new file mode 100755 index 0000000..aba4898 --- /dev/null +++ b/util/fb/testcase/multi-fb-diff-gopkg/circlesearch/common/feedcloud/fbsmeta.fbs @@ -0,0 +1,318 @@ +include "circlesearch/common/feedcloud/common.fbs"; + +// namespace trpc.circlesearch.common; +namespace trpc.circlesearch.common_feedcloud_fbsmeta; +// namespace trpc.group.trpcprotocol.circlesearch.common_feedcloud_fbsmeta; +// namespace circlesearch.common_feedcloud_fbsmeta; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsmeta"; + +enum SyncStatus : int { + SYNC_TO_QZONE = 1, // 同步到空间 + SYNC_FROM_QZONE = 2, // 来自空间 +} + +enum FeedType : int { + TYPE_ACTIVE_FEED = 1, // 主动 feed + TYPE_NOTICE_FEED = 2, // 通知 feed + TYPE_RECOM_FEED = 3, // 推荐 feed + TYPE_ADV_FEED = 4, // 广告 feed +} + +// 关系链类型 +enum RelationType : int { + NO_RELATION = 0, // 没关系 + FOLLOW = 1, // 关注 + MUTUAL_FOLLOW = 2, // 相互关注 + UNCARE = 3, // 拉黑 + FOLLOWED = 4, // 被关注 +} + +// 写操作类型 +enum OperationType : int { + OPERATION_LIKE = 0, // 赞 + OPERATION_COMMENT = 1, // 评论 + OPERATION_REPLY = 2, // 回复 + OPERATION_SYSTEM = 3, // 系统 + OPERATION_FOLLOW = 4, // 关注 +} + +enum NoticeType : int { + TYPE_LIKE = 0, // 赞 + TYPE_COMMENT = 1, // 评论 + TYPE_REPLY = 2, // 回复 + TYPE_SYSTEM = 3, // 系统消息 + TYPE_FOLLOW = 4, // 关注 + // 后续业务可自行扩展 +} + +// StModifyFeedReq.mBitmap 值定义 +enum ModifyFeedBit : int { + MODIFY_FEED_STATUS = 1, // 修改视频状态 第一位 + MODIFY_FEED_CONTENT = 2, // 修改图文内容 第二位 +} + +table StIconInfo { + iconUrl40:string; + iconUrl100:string; + iconUrl140:string; + iconUrl640:string; + iconUrl:string; // 原图 +} + +// 用户信息 +table StUser { + id:string; // QQ 号 + nick:string; + icon:circlesearch.common_feedcloud_fbsmeta.StIconInfo; + desc:string; // 如果有账号描述,则显示账号描述;如果没有,则显示第一个作品标题 + followState:uint; // 登陆者对该用户的关注状态,0:未关注;1:已关注; + type:uint; // 用户类型,业务自己定义 + sex:uint; // 0 表示未知 1 表示男 2 表示女 + birthday:ulong; // 生日 + school:string; // 学校 + location:string; // 所在地 + busiData:[ubyte]; // 业务自行定义 +} + +// 图片挡位信息 +table StImageUrl { + levelType:uint; // 档位,0:原图, 1:小图, 2:中图, 3:大图 + url:string; + width:uint; + height:uint; + busiData:[ubyte]; // 业务自行定义 +} + +// 图片信息 +table StImage { + width:uint; + height:uint; + picUrl:string; + vecImageUrl:[circlesearch.common_feedcloud_fbsmeta.StImageUrl]; // 备选档位 + picId:string; // 图片 id + busiData:[ubyte]; // 业务自行定义 +} + +// 视频档位信息 +table StVideoUrl { + levelType:uint; // 档位,0:原档 + playUrl:string; // 播放地址 + videoPrior:uint; // 视频编码,0:未知;1:H264;2:H265软解;3:H265硬解; + videoRate:uint; // 视频码率kbps + transStatus:uint; // 转码状态,0:默认值;1:转码中;2:转码完成;3:转码失败; + busiData:[ubyte]; // 业务自行定义 +} + +// 视频信息 +table StVideo { + fileId:string; //* 流媒体平台的文件ID + fileSize:uint; //* 文件大小,单位字节 + duration:uint; //* 视频时长,单位毫秒 + width:uint; + height:uint; + playUrl:string; + transStatus:uint; // 转码状态,0:默认值;1:转码中;2:转码完成;3:转码失败; + videoPrior:uint; // 视频编码,0:未知;1:H264;2:H265软解;3:H265硬解; + videoRate:uint; // 视频码率kbps + vecVideoUrl:[circlesearch.common_feedcloud_fbsmeta.StVideoUrl]; // 备选档位 + busiData:[ubyte]; //业务自行定义 +} + +// 赞 +table StLike { + id:string; // 赞 ID + count:uint; // 点赞总数 + status:uint; // 是否点赞:0:否 1:是 + vecUser:[circlesearch.common_feedcloud_fbsmeta.StUser]; // 赞列表 + busiData:[ubyte]; // 业务自行定义 + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 操作人 +} + +// 回复 +table StReply { + id:string; + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; + createTime:ulong; // 发表必填,秒级时间戳 + content:string; + targetUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 被回复人 + busiData:[ubyte]; // 业务自行定义 +} + +// 评论 +table StComment { + id:string; + postUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表必填,秒级时间戳 + createTime:ulong; + content:string; + replyCount:uint; + vecReply:[circlesearch.common_feedcloud_fbsmeta.StReply]; + busiData:[ubyte]; // 业务自行定义 +} + +// 空间分享 +table StShareQzoneInfo { + entries:[circlesearch.common_feedcloud_common.Entry]; +} + +// 分享 +table StShare { + title:string; // 标题 + desc:string; // 描述 + type:uint; // 类型,业务自行定义 + url:string; // 详情 url + author:circlesearch.common_feedcloud_fbsmeta.StUser; // 作者信息 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 分享者信息 + cover:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + video:circlesearch.common_feedcloud_fbsmeta.StVideo; // 视频 + shorturl:string; // 分享短链接 + shareCardInfo:string; // json, 包含 AIO 分享卡片样式的必要信息 + shareQzoneInfo:circlesearch.common_feedcloud_fbsmeta.StShareQzoneInfo; // 分享空间内容 + busiData:[ubyte]; // 业务自行定义 +} + +// 浏览信息 +table StVisitor { + viewCount:uint; // 浏览量 + busiData:[ubyte]; // 业务自行定义 + recomCount:uint; // 被推荐的次数 +} + +// 转发区 +table StRecomForward { + id:string; + title:string; // 标题 + subtitle:string; // 副标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + createTime:ulong; // 发表时间,秒级时间戳 + type:uint; // 业务自行定义 + busiData:[ubyte]; // 业务自行定义 +} + +// feed 摘要 +table StFeedAbstract { + id:string; + title:string; // 标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + pic:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + type:uint; // 业务自行定义 + createTime:ulong; // 发表时间,秒级时间戳 +} + +// 标签信息 +table StTagInfo { + tagId:string; // 标签 id + tagName:string; // 标签名 + tagDec:string; // 描述信息 + userList:[circlesearch.common_feedcloud_fbsmeta.StUser]; // 用户预览列表 + feedList:[circlesearch.common_feedcloud_fbsmeta.StFeedAbstract]; // feed 预览列表 + tagTotalUser:uint; // 标签总成员数 + tagTotalFeed:uint; // 标签总 feed 数 +} + +// 推荐人信息 +table StUserRecomInfo { + user:circlesearch.common_feedcloud_fbsmeta.StUser; // 用户信息 + feedList:[circlesearch.common_feedcloud_fbsmeta.StFeedAbstract]; // feed 预览列表 +} + +// 异形feed,针对推荐、广告或者其他不能用StFeed标识的feed,使用StDittoFeed +table StDittoFeed { + dittoId:uint; // 异形feedId,唯一标识一种Feed,业务自定义 + dittoPatternId:uint; // 异形feed样式Id,业务自定义 + dittoData:[ubyte]; // 异形feed样式数据,业务自定义 +} + +// 用户的 GPS,默认值为非法值,用来表示没有 GPS +table StGPSV2 { + lat:long; // 纬度,实际值 * 1000000 + lon:long; // 经度,实际值 * 1000000 + eType:long; // GPS_WGS84; // 如果是从手机硬件读出来的,要设置此gps为WGS84 // 如果是SDK返回使用GPS_MARS + alt:long; // 海拨 +} + +// POI属性信息 +table StPoiInfoV2 { + poiId:string; // poiID + name:string; // poi名称 + poiType:int; // POI 类型 + typeName:string; // 类型名称 + address:string; // poi地址 + districtCode:int; // 行政区划编码,与身份证号前6位意义相同 + gps:circlesearch.common_feedcloud_fbsmeta.StGPSV2; // 定位的gps坐标 + distance:int; // 离输入点距离,单位:米 + hotValue:int; // 热度值 + phone:string; // 电话 + country:string; // 国家 + province:string; // 省、直辖市、自治区、特别行政区 + city:string; // 地区、地级市、自治州、盟 + poiNum:int; // poi排序位置 + poiOrderType:int; // poi优化类别 + defaultName:string; // 后台推荐的显示标题 + district:string; // 区 + dianPingId:string; // 点评POI ID +} + +// 动态内容 +table StFeed { + id:string; + title:string; // 标题 + subtitle:string; // 副标题 + poster:circlesearch.common_feedcloud_fbsmeta.StUser; // 发表者 + cover:circlesearch.common_feedcloud_fbsmeta.StImage; // 封面 + video:circlesearch.common_feedcloud_fbsmeta.StVideo; // 视频 + content:string; // 图文内容 + type:uint; // feed 媒体类型,业务自行定义 + createTime:ulong; // 发表时间,秒级时间戳 + likeInfo:circlesearch.common_feedcloud_fbsmeta.StLike; // 赞信息 + commentCount:uint; // 评论总数 + vecComment:[circlesearch.common_feedcloud_fbsmeta.StComment]; // 评论列表 + share:circlesearch.common_feedcloud_fbsmeta.StShare; // 分享信息 + visitorInfo:circlesearch.common_feedcloud_fbsmeta.StVisitor; // 浏览信息 + images:[circlesearch.common_feedcloud_fbsmeta.StImage]; // 多图 + status:uint; // 业务自己定义 + poiInfo:circlesearch.common_feedcloud_fbsmeta.StPoiInfoV2; // POI 属性信息 + adBuffer:[ubyte]; // 广告 feed + busiData:[ubyte]; // 业务自行定义 + isRecomFd:bool; // 是否用户推荐转发 feed + recomForward:circlesearch.common_feedcloud_fbsmeta.StRecomForward; // 推荐转发区域 + tagInfos:[circlesearch.common_feedcloud_fbsmeta.StTagInfo]; // 标签信息 + syncStatus:uint; // 同步状态 + busiReport:[ubyte]; // 上报透传字段,读下发,上报带上 + dittoFeed:circlesearch.common_feedcloud_fbsmeta.StDittoFeed; // 异形 feed + feedType:uint; // feed 类型,见 FEED_TYPE + busiTransparent:[circlesearch.common_feedcloud_common.BytesEntry]; // feed 层面的透传字段,key 业务自行定义 +} + +// 关系链信息 +table StRelationInfo { + id:string; // 对方账号信息 + relation:uint; // 关系类型,见 RELATION_TYPE + busiData:[ubyte]; // 业务特有信息,结构体自行定义 +} + +// 写操作类型 +table StOperation { + opType:uint; // 操作类型,见 OPERATION_TYPE + opUser:circlesearch.common_feedcloud_fbsmeta.StUser; // 操作人信息 + opTime:ulong; // 操作时间 + comment:circlesearch.common_feedcloud_fbsmeta.StComment; // 如果是评论或者回复,当前评论或者回复详情放这里 + like:circlesearch.common_feedcloud_fbsmeta.StLike; // 点赞信息 + busiData:[ubyte]; // 业务自行定义 +} + +// 被动通知 +table StNotice { + feedId:string; + noticeType:uint; // 通知类型,见 NOTICE_TYPE + createTime:ulong; // 通知时间,秒级时间戳 + operation:circlesearch.common_feedcloud_fbsmeta.StOperation; // 操作信息 + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; // feed 信息 + busiData:[ubyte]; // 业务自行定义 +} + +table StReportInfo { + id:string; // feed id + busiReport:[ubyte]; // 上报透传字段,对应StFeed busiReport +} + diff --git a/util/fb/testcase/multi-fb-diff-gopkg/fbsread.fbs b/util/fb/testcase/multi-fb-diff-gopkg/fbsread.fbs new file mode 100755 index 0000000..d65408e --- /dev/null +++ b/util/fb/testcase/multi-fb-diff-gopkg/fbsread.fbs @@ -0,0 +1,223 @@ +include "circlesearch/common/feedcloud/fbsmeta.fbs"; +include "circlesearch/common/feedcloud/common.fbs"; + +// namespace trpc.circlesearch.common; +namespace trpc.circlesearch.common_feedcloud_fbsread; +// namespace trpc.group.trpcprotocol.circlesearch.common_feedcloud_fbsread; +// namespace circlesearch.common_feedcloud_fbsread; + +attribute "go_package=trpc.group/trpcprotocol/circlesearch/common_feedcloud_fbsread"; + +enum FromType : int { + TERMINAL = 0, + H5 = 1, + ADMIN = 2, + SVR = 3, +} + +// 拉取 feed 详情 +table StGetFeedDetailReq { + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + from:int; // 请求来源,0:客户端,1:H5,2:管理端 + userId:string; // 用户ID + feedId:string; // FeedID + createTime:ulong; // Feed发表秒级时间戳 + adrequest:[ubyte]; // 广告请求 + adAttachInfo:string; // 广告透传 + bizReqData:[ubyte]; // 业务异化请求,结构体自行定义 +} + +table StGetFeedDetailRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + detailUrl:string; + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; // 当前feed详情 + vecRcmdFeed:[circlesearch.common_feedcloud_fbsmeta.StFeed]; // 相关推荐feed + share:circlesearch.common_feedcloud_fbsmeta.StShare; // 分享信息 + isFinish:uint; // feed是否拉取完毕,0:否;1:是 + adAttachInfo:string; // 广告透传 + busiRspData:[ubyte]; // 业务异化回包,结构体自行定义 +} + +// 拉取feed列表 +table StGetFeedListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + listNum:uint; // 一页拉取个数 + from:int; // 请求来源 参考FROM_TYPE + // 当请求与当前feed相关时填写,只需填写feedid,createTime,poster结构和busiTransparent字段不需要整个feed结构 + feed:circlesearch.common_feedcloud_fbsmeta.StFeed; + adrequest:[ubyte]; // 广告请求 + adAttachInfo:string; // 广告透传 + feedAttachInfo:string; // feed列表透传 + source:int; // 请求源,业务自行定义 + busiReqData:[ubyte]; // 业务异化请求,结构体自行定义 +} + +table StGetFeedListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + vecFeed:[circlesearch.common_feedcloud_fbsmeta.StFeed]; + isFinish:uint; // 是否拉取完毕,0:否;1:是 + user:circlesearch.common_feedcloud_fbsmeta.StUser; // 登录人的个人信息 + adAttachInfo:string; // 广告透传 + feedAttachInfo:string; // feed透传 + busiRspData:[ubyte]; // 业务异化回包,结构体自行定义 +} + +// 拉取评论列表 +table StGetCommentListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + userId:string; // 用户ID + feedId:string; // FeedID + listNum:uint; // 一页拉取个数 + from:int; // 请求来源,0:客户端,1:H5,2:管理端 + feedAttachInfo:string; // feed透传 + busiReqData:[ubyte]; // 业务异化请求,结构体自行定义 + likeKey:string; // 赞key +} + +table StGetCommentListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + vecComment:[circlesearch.common_feedcloud_fbsmeta.StComment]; + totalNum:uint; + isFinish:uint; + feedAttachInfo:string; + busiRspData:[ubyte]; +} + +table StGetMainPageReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + userId:string; + from:int; + feedAttachInfo:string; + busiReqData:[ubyte]; +} + +table StGetMainPageRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + user:circlesearch.common_feedcloud_fbsmeta.StUser; + feedCount:uint; + fansCount:uint; + followCount:uint; + vecFeed:[circlesearch.common_feedcloud_fbsmeta.StFeed]; + isFinish:uint; + share:circlesearch.common_feedcloud_fbsmeta.StShare; + feedAttachInfo:string; + busiRspData:[ubyte]; +} + +table StGetNoticeListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + listNum:uint; + feedAttachInfo:string; + pageType:uint; + busiReqData:[ubyte]; +} + +table StGetNoticeListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + vecNotice:[circlesearch.common_feedcloud_fbsmeta.StNotice]; + totalNum:uint; + isFinish:uint; + feedAttachInfo:string; + busiRspData:[ubyte]; +} + +table StGetBusiInfoReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + busiReqData:[ubyte]; +} + +table StGetBusiInfoRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + busiRspData:[ubyte]; +} + +table StGetFollowListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + userId:string; + attachInfo:string; + count:uint; + busiReqData:[ubyte]; +} + +table StGetFollowListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + attachInfo:string; + hasNext:uint; + relationInfo:[circlesearch.common_feedcloud_fbsmeta.StRelationInfo]; + busiRspData:[ubyte]; +} + +table StGetFansListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + userId:string; + attachInfo:string; + count:long; + busiReqData:[ubyte]; +} + +table StGetFansListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + attachInfo:string; + hasNext:uint; + relationInfo:[circlesearch.common_feedcloud_fbsmeta.StRelationInfo]; + busiRspData:[ubyte]; +} + +table StGetRecomTagListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + gpsInfo:circlesearch.common_feedcloud_fbsmeta.StGPSV2; + busiReqData:[ubyte]; +} + +table StGetRecomTagListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + tagList:[circlesearch.common_feedcloud_fbsmeta.StTagInfo]; + busiRspData:[ubyte]; +} + +table StGetRecomUserListReq { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + needFeeds:bool; + attachInfo:string; + busiReqData:[ubyte]; +} + +table StGetRecomUserListRsp { + + extInfo:circlesearch.common_feedcloud_common.StCommonExt; + userRecoms:[circlesearch.common_feedcloud_fbsmeta.StUserRecomInfo]; + attachInfo:string; + isFinish:uint; + busiRspData:[ubyte]; +} + +rpc_service ComReader { + GetFeedList(StGetFeedListReq):StGetFeedListRsp; + GetFeedDetail(StGetFeedDetailReq):StGetFeedDetailRsp; + GetMainpage(StGetMainPageReq):StGetMainPageRsp; + GetCommentList(StGetCommentListReq):StGetCommentListRsp; + GetNoticeList(StGetNoticeListReq):StGetNoticeListRsp; + GetFollowList(StGetFollowListReq):StGetFollowListRsp; + GetFansList(StGetFansListReq):StGetFansListRsp; + GetBusiInfo(StGetBusiInfoReq):StGetBusiInfoRsp; + GetRecomTagList(StGetRecomTagListReq):StGetRecomTagListRsp; + GetRecomUserList(StGetRecomUserListReq):StGetRecomUserListRsp; +} diff --git a/util/fb/testcase/normal/hello.fbs b/util/fb/testcase/normal/hello.fbs new file mode 100755 index 0000000..5292603 --- /dev/null +++ b/util/fb/testcase/normal/hello.fbs @@ -0,0 +1,9 @@ +include "message.fbs"; +namespace hello; + +attribute "go_package=trpc.group/examples/hello"; + + +rpc_service hello_svr { + Hello(HelloReq):HelloRsp; +} \ No newline at end of file diff --git a/util/fb/testcase/normal/message.fbs b/util/fb/testcase/normal/message.fbs new file mode 100755 index 0000000..0f537e0 --- /dev/null +++ b/util/fb/testcase/normal/message.fbs @@ -0,0 +1,11 @@ +namespace hello; + +attribute "go_package=trpc.group/examples/hello"; + +table HelloReq { + Message:string; +} + +table HelloRsp { + Message:string; +} \ No newline at end of file diff --git a/util/fs/copy.go b/util/fs/copy.go new file mode 100644 index 0000000..db6af5a --- /dev/null +++ b/util/fs/copy.go @@ -0,0 +1,92 @@ +package fs + +import ( + "io" + "io/ioutil" + + "os" + "path/filepath" +) + +// Copy copies src to dest, doesn't matter if src is a directory or a file +func Copy(src, dest string) error { + info, err := os.Lstat(src) + if err != nil { + return err + } + return copy(src, dest, info) +} + +// copy dispatches copy-funcs according to the mode. +// Because this "copy" could be called recursively, +// "info" MUST be given here, NOT nil. +func copy(src, dest string, info os.FileInfo) error { + if info.Mode()&os.ModeSymlink != 0 { + return lcopy(src, dest, info) + } + if info.IsDir() { + return dcopy(src, dest, info) + } + return fcopy(src, dest, info) +} + +// fcopy is for just a file, +// with considering existence of parent directory +// and file permission. +func fcopy(src, dest string, info os.FileInfo) error { + if err := os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil { + return err + } + + f, err := os.Create(dest) + if err != nil { + return err + } + defer f.Close() + + if err = os.Chmod(f.Name(), info.Mode()); err != nil { + return err + } + + s, err := os.Open(src) + if err != nil { + return err + } + defer s.Close() + + _, err = io.Copy(f, s) + return err +} + +// dcopy is for a directory, +// with scanning contents inside the directory +// and pass everything to "copy" recursively. +func dcopy(srcdir, destdir string, info os.FileInfo) error { + if err := os.MkdirAll(destdir, info.Mode()); err != nil { + return err + } + + contents, err := ioutil.ReadDir(srcdir) + if err != nil { + return err + } + + for _, content := range contents { + cs, cd := filepath.Join(srcdir, content.Name()), filepath.Join(destdir, content.Name()) + if err := copy(cs, cd, content); err != nil { + // If any error, exit immediately + return err + } + } + return nil +} + +// lcopy is for a symlink, +// with just creating a new symlink by replicating src symlink. +func lcopy(src, dest string, info os.FileInfo) error { + src, err := os.Readlink(src) + if err != nil { + return err + } + return os.Symlink(src, dest) +} diff --git a/util/fs/copy_test.go b/util/fs/copy_test.go new file mode 100644 index 0000000..0a09017 --- /dev/null +++ b/util/fs/copy_test.go @@ -0,0 +1,78 @@ +package fs + +import ( + "errors" + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" +) + +func TestCopy(t *testing.T) { + type args struct { + src string + dest string + } + tests := []struct { + name string + args args + wantErr bool + }{ + // TODO: Add test cases. + {"1-copy/fa", args{"copy/fa", "target/fa"}, false}, + {"2-copy/fa", args{"copy/fa", "target/copy/fa"}, false}, + {"3-copy/d", args{"copy/d", "target/d"}, false}, + {"4-copy/d", args{"copy/d", "target/e/d"}, false}, + } + tmpdir := filepath.Join(wd, "testcase/target") + err := os.MkdirAll(tmpdir, os.ModePerm) + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(tmpdir) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + src := filepath.Join(wd, "testcase", tt.args.src) + dest := filepath.Join(wd, "testcase", tt.args.dest) + + if err := Copy(src, dest); (err != nil) != tt.wantErr { + t.Errorf("Copy() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_lcopy(t *testing.T) { + t.Run("case fail", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(os.Readlink, func(name string) (string, error) { + return "", errors.New("fake error") + }) + p.ApplyFunc(os.Symlink, func(oldname, newname string) error { + return nil + }) + defer p.Reset() + + info, _ := os.Lstat("copy/a") + err := lcopy("src", "dst", info) + require.NotNil(t, err) + }) + + t.Run("case succ", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(os.Readlink, func(name string) (string, error) { + return "", nil + }) + p.ApplyFunc(os.Symlink, func(oldname, newname string) error { + return nil + }) + defer p.Reset() + + info, _ := os.Lstat("copy/a") + err := lcopy("src", "dst", info) + require.Nil(t, err) + }) +} diff --git a/util/fs/file.go b/util/fs/file.go new file mode 100644 index 0000000..80cbc5f --- /dev/null +++ b/util/fs/file.go @@ -0,0 +1,114 @@ +// Package fs implements cross-platform file system capabilities. +package fs + +import ( + "fmt" + "os" + "path/filepath" + "sort" + + "trpc.group/trpc-go/trpc-cmdline/util/lang" + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// BaseNameWithoutExt return basename without extension of `filename`, +// in which `filename` may contains directory. +func BaseNameWithoutExt(filename string) string { + return lang.TrimRight(".", filepath.Base(filename)) +} + +// LocateFile returns the absolute path of proto file. +// +// To ensure that protofile can be found, +// protodirs needs to provide the parent path of protofile and cannot be the parent path's parent path. +func LocateFile(protofile string, protodirs []string) (string, error) { + if filepath.IsAbs(protofile) { + _, err := os.Lstat(protofile) + if err != nil { + return "", fmt.Errorf("protofile stat %s err: %w", protofile, err) + } + return protofile, nil + } + + // always add current directory into search dirs + abs, err := filepath.Abs(".") + if err != nil { + return "", fmt.Errorf("filepath.Abs . err: %w", err) + } + + // If we can find the protofile under the current directory, + // directly return to prevent possible conflicts resulting from the relative path in protofile. + // Reference: https://mk.woa.com/q/286784 + fp := filepath.Join(abs, protofile) + if info, err := os.Lstat(fp); err == nil && !info.IsDir() { + return fp, nil + } + + protodirs = append(protodirs, abs) + protodirs = UniqFilePath(protodirs) + + // Find the absolute path of protofile. + log.Debug("protocolfile: %s", protofile) + log.Debug("protodirs: %s", protodirs) + fpaths, err := getPbFilePathList(protofile, protodirs) + if err != nil { + return "", fmt.Errorf("get pb file path listerr: %w", err) + } + + // `-protofile=abc/d.proto`, works like `-protodir=abc -protofile=d.proto` + return filepath.Abs(fpaths[0]) +} + +func getPbFilePathList(protofile string, dirs []string) ([]string, error) { + fpaths := []string{} + for _, dir := range dirs { + fp := filepath.Join(dir, protofile) + inf, err := os.Lstat(fp) + if err == nil && !inf.IsDir() { + fpaths = append(fpaths, fp) + } + } + if len(fpaths) == 0 { + return nil, fmt.Errorf("%s not found in dirs: %v", protofile, dirs) + } + if len(fpaths) > 1 { + return nil, fmt.Errorf("%s found duplicate ones: %v", protofile, fpaths) + } + return fpaths, nil +} + +// UniqFilePath is used to deduplicate file paths in a slice. +func UniqFilePath(dirs []string) []string { + set := map[string]struct{}{} + for _, p := range dirs { + abs, _ := filepath.Abs(p) + set[abs] = struct{}{} + } + + uniq := []string{} + for dir := range set { + uniq = append(uniq, dir) + } + sort.Strings(uniq) + + return uniq +} + +// PrepareOutputdir create outputdir if it doesn't exist, +// return error if `outputdir` existed while it is not a directory, +// return error if any other error occurs. +func PrepareOutputdir(outputdir string) (err error) { + fin, err := os.Lstat(outputdir) + if err != nil { + if !os.IsNotExist(err) { + return err + } + return os.MkdirAll(outputdir, os.ModePerm) + } + + if !fin.IsDir() { + return fmt.Errorf("target %s existed, but not a directory", outputdir) + } + + return nil +} diff --git a/util/fs/file_test.go b/util/fs/file_test.go new file mode 100644 index 0000000..a547d99 --- /dev/null +++ b/util/fs/file_test.go @@ -0,0 +1,113 @@ +package fs + +import ( + "os" + "path/filepath" + "reflect" + "testing" +) + +var wd string + +func TestMain(m *testing.M) { + d, err := os.Getwd() + if err != nil { + panic(err) + } + wd = d + os.Exit(m.Run()) +} + +func TestBaseFileNameWithoutExt(t *testing.T) { + type args struct { + filename string + } + tests := []struct { + name string + args args + want string + }{ + {"1-trpc.proto", args{"trpc.proto"}, "trpc"}, + {"2-hello.world.proto", args{"hello.world.proto"}, "hello.world"}, + {"3-trpc.app.server.go", args{"trpc.app.server.go"}, "trpc.app.server"}, + {"4-trpc.group/group/repo/trpc.app.proto", args{"trpc.group/group/repo/trpc.app.proto"}, "trpc.app"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := BaseNameWithoutExt(tt.args.filename); got != tt.want { + t.Errorf("BaseNameWithoutExt() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestLocateProtofileDir(t *testing.T) { + + tests := []struct { + name string + filename string + search string + wantErr bool + }{ + {"1-good.dat", "good.dat", filepath.Join(wd, "testcase/a/b/"), false}, + {"2-bad.dat", "bad.dat", filepath.Join(wd, "testcase/a/b/c/"), false}, + {"3-hello.dat", "hello.dat", filepath.Join(wd, "testcase/a/b/c/d/"), false}, + {"4-notexist.dat", "notexit.dat", filepath.Join(wd, "testcase/a/b/c/d/"), true}, + {"5-good.dat", "notexit.dat", filepath.Join(wd, "testcase/"), true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := LocateFile(tt.filename, []string{tt.search}) + if (err != nil) != tt.wantErr { + t.Errorf("LocateFile() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} + +func TestUniqFilePath(t *testing.T) { + type args struct { + dirs []string + } + tests := []struct { + name string + args args + want []string + }{ + {"testcase-1", args{[]string{"/a", "/b", "/a"}}, []string{"/a", "/b"}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := UniqFilePath(tt.args.dirs); !reflect.DeepEqual(got, tt.want) { + t.Errorf("UniqFilePath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestPrepareOutputdir(t *testing.T) { + type args struct { + outputdir string + } + tests := []struct { + name string + args args + wantErr bool + }{ + {"testcase-1", args{filepath.Join(wd, "testcase/a/")}, false}, // target dir already existed, return nil + {"testcase-2", args{filepath.Join(wd, "testcase/a/b/good.dat")}, true}, // target existed but not dir, return error + {"testcase-3", args{filepath.Join(wd, "testcase/fff")}, false}, // target dir not existed, create it, return nil + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := PrepareOutputdir(tt.args.outputdir) + if (err != nil) != tt.wantErr { + t.Errorf("PrepareOutputdir() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.name == "testcase-3" { + os.RemoveAll(tt.args.outputdir) + } + }) + } +} diff --git a/util/fs/move.go b/util/fs/move.go new file mode 100644 index 0000000..1f123cb --- /dev/null +++ b/util/fs/move.go @@ -0,0 +1,237 @@ +package fs + +import ( + "os" + "path/filepath" + "syscall" +) + +const lstat = "lstat" + +// Move move `src` to `dest` +// +// the behavior of fs.Move is consistent with bash shell `mv` command: +// +// when move a file, actions are following: +// ------------------------------------------------------------------------------------------------ +// | No. | src existed | src type | dst existed | dst type | behavior | +// ------------------------------------------------------------------------------------------------ +// | 1 | False | - | - | - | error: No such file or directory | +// ------------------------------------------------------------------------------------------------ +// | 2 | True | File | False | - | if dir(dst) existed: | +// | | | | | | - Yes, is dir, mv `src` to dir(dst) | +// | | | | | | - Yes, not dir, err: Not a directory | +// | | | | | | - No, err: No such file or directory | +// ------------------------------------------------------------------------------------------------ +// | 3 | True | File | True | Folder | if dst/basename(src) existed: | +// | | | | | | - Yes, mv `src` to dst/basename(src) | +// | | | | | | - No, mv `src` to dst/basename(src) | +// ------------------------------------------------------------------------------------------------ +// | 4 | True | File | True | File | mv `src` to dst | +// ------------------------------------------------------------------------------------------------ +// +// when move a directory, actions are following: +// ------------------------------------------------------------------------------------------------ +// | 5 | True | Folder | False | - | if dir(dst) existed: | +// | | | | | | - Yes, is dir, mv `src` to dir(dst) | +// | | | | | | - Yes, not dir, err: File Exists | +// | | | | | | - No, err: No such file or directory | +// ------------------------------------------------------------------------------------------------ +// | 6 | True | Folder | True | File | error: File Already Existed | +// ------------------------------------------------------------------------------------------------ +// | 7 | True | Folder | True | Folder | t = dst/basename(src), if t existed: | +// | | | | | | - Yes, t empty, mv src to t | +// | | | | | | - t notempty, err: t Not empty | +// | | | | | | - No, mv src to t | +// ------------------------------------------------------------------------------------------------ +// +// Why keep the behavior consistent? It makes the usage much more friendly when it behaves as users expected. +func Move(src, dst string) error { + var ( + inf os.FileInfo + err error + ) + + // check whether `src` is valid or not + if inf, err = os.Lstat(src); err != nil { + return err + } + + // move directory + if inf.IsDir() { + return moveDirectory(src, dst) + } + + // move file + return moveFile(src, dst) +} + +// moveFile move a file `src` to `dst` +// +// `src` is a normal file, dst can be a file or directory. +// 1. if `dst` not existed +// - if dir(dst) existed and is a directory, then move `src` under dir(dst), +// - if dir(dst) existed and not a directory, return err: &PathError(Op: "lstat", Path: dir(dstErr:), syscall.EEXIST} +// - if dir(dst) not existed, return err: &PathError(Op: "lstat", Path: dir(dstErr:), os.ENOENT} +// +// 2. if `dst` existed +// - if dst is a normal file, rename src to dst +// - if dst is a folder, rename src to dst/basename(src) +func moveFile(src, dst string) error { + dstInf, err := os.Lstat(dst) + + // if dst existed + if err == nil { + if !dstInf.IsDir() { + return Rename(src, dst) + } + + p := filepath.Join(dst, filepath.Base(src)) + return Rename(src, p) + } + + if !os.IsNotExist(err) { + return err + } + + // if dst not existed + p := filepath.Dir(dst) + if inf, err := os.Lstat(p); err != nil { + return err + } else { + // p is a symlink to valid directory + if inf.Mode()&os.ModeSymlink != 0 { + yes, err := isSymLinkToDir(p) + if err != nil { + return err + } + if !yes { + return &os.PathError{Op: "lstat", Path: p, Err: syscall.EEXIST} + } + return Rename(src, dst) + } + // p isn't directory, neither + if !inf.IsDir() { + return &os.PathError{Op: "lstat", Path: p, Err: syscall.EEXIST} + } + return Rename(src, dst) + } +} + +// isSymLinkToDir check if symlink `p` points to a valid directory +func isSymLinkToDir(symlink string) (yes bool, err error) { + linkTo, err := filepath.EvalSymlinks(symlink) + if err != nil { + return + } + + fin, err := os.Lstat(linkTo) + if err != nil { + return + } + + if !fin.IsDir() { + return false, nil + } + return true, nil +} + +// moveDirectory move a directory `src` to `dst` +// +// `src` is a directory, dst should always be a directory. +// 1. if `dst` existed +// - if `dst` is not a directory, return error &PathError{Op: "lstat", Path: dst, Err: os.EEXIST} +// - if `dst` is a directory +// - if dst/basename(src) is empty, then rename src to dst/basename(src) +// - if dst/basename(src) not empty, return error &PathError{Op: "lstat", Path: dst, Err: syscall.ENOTEMPTY} +// +// 2. if `dst` not existed +// - if dir(dst) existed, rename src to dst +// - if dir(dst) not existed, return error &PathError{Op: "lstat", Path: dst, Err: syscall.ENOENT} +func moveDirectory(src, dst string) error { + dstInf, err := os.Lstat(dst) + + // if dst existed + if err == nil { + + if !dstInf.IsDir() { + return &os.PathError{Op: "lstat", Path: dst, Err: syscall.EEXIST} + } + + target := filepath.Join(dst, filepath.Base(src)) + inf, err := os.Lstat(target) + if err != nil { + if os.IsNotExist(err) { + return Rename(src, target) + } + return err + } + + if !inf.IsDir() { + return &os.PathError{Op: "lstat", Path: target, Err: syscall.EEXIST} + } + + files, err := os.ReadDir(target) + if err != nil { + return err + } + if len(files) != 0 { + return &os.PathError{Op: "lstat", Path: target, Err: syscall.ENOTEMPTY} + } + + if err = os.RemoveAll(target); err != nil { + return err + } + return Rename(src, target) + } + + // if dst not existed + inf, err := os.Lstat(filepath.Dir(dst)) + if err != nil { + return err + } + if !inf.IsDir() { + return &os.PathError{Op: "lstat", Path: filepath.Base(dst), Err: syscall.EEXIST} + } + return Rename(src, dst) +} + +func coverNoFileTarget(src string, target string) error { + files, err := os.ReadDir(target) + if err != nil { + return err + } + if len(files) != 0 { + return &os.PathError{Op: lstat, Path: target, Err: syscall.ENOTEMPTY} + } + + if err = os.RemoveAll(target); err != nil { + return err + } + if err = Copy(src, target); err != nil { + return err + } + return os.RemoveAll(src) +} + +// Rename fs.Rename is just a wrapper of syscall rename, +// it may fail if renamimg across different devices, so we must provide +// a solution like: copy(src,dst)+rm(dst). +// +// see: https://groups.google.com/g/golang-dev/c/5w7Jmg_iCJQ +func Rename(src, dst string) error { + var err error + if src, err = filepath.Abs(src); err != nil { + return err + } + if dst, err = filepath.Abs(dst); err != nil { + return err + } + if src == dst { + return nil + } + if err := Copy(src, dst); err != nil { + return err + } + return os.RemoveAll(src) +} diff --git a/util/fs/move_test.go b/util/fs/move_test.go new file mode 100644 index 0000000..52dfa9b --- /dev/null +++ b/util/fs/move_test.go @@ -0,0 +1,152 @@ +package fs + +import ( + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" +) + +func TestMove(t *testing.T) { + type args struct { + src string + dst string + } + + //backup + src := filepath.Join(wd, "testcase/move") + dst := filepath.Join(wd, "testcase/move.bak") + err := Copy(src, dst) + if err != nil { + t.Fatal(err) + } + defer func() { + _ = os.RemoveAll(src) + _ = Rename(dst, src) + }() + + tests := []struct { + name string + args args + wantErr bool + }{ + // testcases for move a file + {"case1.1-src-notexist-dst-notexist", args{"notexist", "move/notexist"}, true}, + {"case1.2-src-notexist-dst-exist", args{"notexist", "move/d"}, true}, + {"case2.1-src-file-dst-notexist-dir(dst)isfolder", args{"move/a", "move/d/a"}, false}, + {"case2.2-src-file-dst-notexist-dir(dst)isnotfolder", args{"move/b", "move/nf/a"}, true}, + {"case2.3-src-file-dst-notexist-dir(dst)notexist", args{"move/b", "move/mf/a"}, true}, + {"case3.1-src-file-dst-folder-dst/basename(src)-exist", args{"move/b", "move/d"}, false}, + {"case3.2-src-file-dst-folder-dst/basename(src)-notexist", args{"move/c", "move/d"}, false}, + {"case4.1-src-file-dst-file", args{"move/fd", "move/fd"}, false}, + // testcases for move a directory + {"case5.1-src-folder-dst-notexist-dir(dst)folder", args{"move/d", "move/e/d"}, false}, + {"case5.2-src-folder-dst-notexist-dir(dst)file", args{"move/d", "move/nf/d"}, true}, + {"case5.3-src-folder-dst-notexist-dir(dst)notexist", args{"move/e", "move/notexist/e"}, true}, + {"case6.1-src-folder-dst-file", args{"move/e", "move/nf"}, true}, + {"case7.1-src-folder-dst-folder-dst/basename(src)existed+empty", args{"move/z", "move/x/y/"}, false}, + {"case7.2-src-folder-dst-folder-dst/basename(src)existed_notempty", args{"move/z1", "move/x/"}, true}, + {"case7.3-src-folder-dst-folder-dst/basename(src)notexist", args{"move/z1", "move/q"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + src := filepath.Join(wd, "testcase", tt.args.src) + dst := filepath.Join(wd, "testcase", tt.args.dst) + if err := Move(src, dst); (err != nil) != tt.wantErr { + t.Errorf("Move() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func Test_isSymLinkToDir(t *testing.T) { + src := filepath.Join(wd, "testcase/move") + type args struct { + symlink string + } + tests := []struct { + name string + args args + wantYes bool + wantErr bool + }{ + { + name: "case1-exist-file", + args: args{ + symlink: filepath.Join(src, "a"), + }, + wantYes: false, + wantErr: false, + }, + { + name: "case2-exist-dir", + args: args{ + symlink: filepath.Join(src, "d"), + }, + wantYes: true, + wantErr: false, + }, + { + name: "case3-unknown-path", + args: args{ + symlink: "unknown_path", + }, + wantYes: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotYes, err := isSymLinkToDir(tt.args.symlink) + if (err != nil) != tt.wantErr { + t.Errorf("isSymLinkToDir() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotYes != tt.wantYes { + t.Errorf("isSymLinkToDir() gotYes = %v, want %v", gotYes, tt.wantYes) + } + }) + } +} + +func Test_moveDirectory(t *testing.T) { + type args struct { + src string + dst string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "case1-move_but_dst_not_dir", + args: args{ + src: filepath.Join(wd, "testcase/move/a"), + dst: filepath.Join(wd, "testcase/move/b"), + }, + wantErr: true, + }, + { + name: "case2-move_and_dst_not_exist", + args: args{ + src: filepath.Join(wd, "testcase/move/a"), + dst: filepath.Join(wd, "testcase/move/d"), + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc(Rename, func(oldpath, newpath string) error { + return nil + }) + defer p.Reset() + + if err := moveDirectory(tt.args.src, tt.args.dst); (err != nil) != tt.wantErr { + t.Errorf("moveDirectory() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/util/fs/testcase/a/b/c/bad.dat b/util/fs/testcase/a/b/c/bad.dat new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/a/b/c/d/hello.dat b/util/fs/testcase/a/b/c/d/hello.dat new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/a/b/good.dat b/util/fs/testcase/a/b/good.dat new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/d/fd b/util/fs/testcase/copy/d/fd new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/e/fe b/util/fs/testcase/copy/e/fe new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/f/ff b/util/fs/testcase/copy/f/ff new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/fa b/util/fs/testcase/copy/fa new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/fb b/util/fs/testcase/copy/fb new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/copy/fc b/util/fs/testcase/copy/fc new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/a b/util/fs/testcase/move/a new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/b b/util/fs/testcase/move/b new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/c b/util/fs/testcase/move/c new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/d/b b/util/fs/testcase/move/d/b new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/e/f b/util/fs/testcase/move/e/f new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/fd b/util/fs/testcase/move/fd new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/fe b/util/fs/testcase/move/fe new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/ff b/util/fs/testcase/move/ff new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/nf b/util/fs/testcase/move/nf new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/x/z1/f1 b/util/fs/testcase/move/x/z1/f1 new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/x/z1/f2 b/util/fs/testcase/move/x/z1/f2 new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/z/f1 b/util/fs/testcase/move/z/f1 new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/z/f2 b/util/fs/testcase/move/z/f2 new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/z1/f1 b/util/fs/testcase/move/z1/f1 new file mode 100644 index 0000000..e69de29 diff --git a/util/fs/testcase/move/z1/f2 b/util/fs/testcase/move/z1/f2 new file mode 100644 index 0000000..e69de29 diff --git a/util/lang/lang.go b/util/lang/lang.go new file mode 100644 index 0000000..914f144 --- /dev/null +++ b/util/lang/lang.go @@ -0,0 +1,405 @@ +// Package lang encapsulates language-related functionality. +package lang + +import ( + "bufio" + "fmt" + "os" + "path/filepath" + "strings" + "unicode" + + "github.com/iancoleman/strcase" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" +) + +// PBSimplifyGoType determine whether to use fullyQualifiedPackageName or not, +// if the `fullTypeName` occur in code of `package goPackageName`, `package` part +// should be removed. +func PBSimplifyGoType(fullTypeName string, goPackageName string) string { + idx := strings.LastIndex(fullTypeName, ".") + if idx <= 0 { + panic(fmt.Sprintf("invalid fullyQualifiedType: %s", fullTypeName)) + } + + pkg := fullTypeName[0:idx] + typ := fullTypeName[idx+1:] + + if pkg == goPackageName { + return typ + } + return fullTypeName +} + +// PBGoType convert `t` to go style (like a.b.c.hello, it'll be changed to a_b_c.Hello) +func PBGoType(t string) string { + var prefix string + + idx := strings.LastIndex(t, "/") + if idx >= 0 { + prefix = t[:idx] + t = t[idx+1:] + } + + idx = strings.LastIndex(t, ".") + if idx <= 0 { + panic(fmt.Sprintf("invalid go type: %s", t)) + } + + gopkg := PBGoPackage(t[0:idx]) + msg := t[idx+1:] + + return GoExport(prefix + gopkg + "." + msg) +} + +// PBGoPackage convert a.b.c to a_b_c +// +// if there's following option `go_package="trpc.group/hello;world"`, +// then PBGoPackage should return `world` instead of `hello`. +func PBGoPackage(pkgName string) string { + var ( + prefix string + pkg string + ) + idx := strings.LastIndex(pkgName, "/") + if idx < 0 { + pkg = pkgName + } else { + prefix = pkgName[0:idx] + pkg = pkgName[idx+1:] + } + + pkg = strings.Replace(pkg, "-", "_", -1) + gopkg := strings.Replace(pkg, ".", "_", -1) + _ = prefix + + return TrimLeft(";", gopkg) +} + +// GoExport export go type +func GoExport(typ string) string { + idx := strings.LastIndex(typ, ".") + if idx < 0 { + return strings.Title(typ) + } + return typ[0:idx] + "." + strings.Title(typ[idx+1:]) +} + +// SplitList split string `str` via delimiter `sep` into a list of string +func SplitList(sep, str string) []string { + return strings.Split(str, sep) +} + +// ReverseList reverse the order from end to start for a list. +func ReverseList(s []string) []string { + for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { + s[i], s[j] = s[j], s[i] + } + return s +} + +// TrimRight trim right substr starting at `sep` +func TrimRight(sep, str string) string { + idx := strings.LastIndex(str, sep) + if idx < 0 { + return str + } + return str[:idx] +} + +// TrimLeft trim left substr starting at `sep` +func TrimLeft(sep, str string) string { + idx := strings.Index(str, sep) + if idx < 0 { + return str + } + return str[idx+len(sep):] +} + +// Title uppercase the first character of `s` +func Title(s string) string { + for k, v := range s { + return string(unicode.ToUpper(v)) + s[k+1:] + } + return "" +} + +// UnTitle make the first character of s lowercase +func UnTitle(s string) string { + for k, v := range s { + return string(unicode.ToLower(v)) + s[k+1:] + } + return "" +} + +// GoFullyQualifiedType convert $repo/$pkg.$type to $realpkg.$type, where $realpkg is calculated +// by `package directive` and `go_package` file option. +// +// For example: +// ```proto +// option go_package="github.com/abc/abc;def" +// message XXXX{} +// ``` +// In this example: +// - importPath should be `import def "github.com/abc/abc"` +// - typeName should be `def.XXXX` rather than `abc.XXXX`. +func GoFullyQualifiedType(pbFullyQualifiedType string, nfd *descriptor.FileDescriptor) string { + return goFullyQualifiedTypeCommon(pbFullyQualifiedType, nfd, goFullyQualifiedType) +} + +// GoFullyQualifiedTypeX is for replacing GoFullyQualifiedType. +func GoFullyQualifiedTypeX(pbFullyQualifiedType string, nfd *descriptor.FileDescriptor) string { + return goFullyQualifiedTypeCommon(pbFullyQualifiedType, nfd, goFullyQualifiedTypeX) +} + +func goFullyQualifiedTypeCommon( + pbFullyQualifiedType string, + nfd *descriptor.FileDescriptor, + rpcMessageTypeHandle func(pb, typ string, nfd *descriptor.FileDescriptor) string, +) string { + idx := strings.LastIndex(pbFullyQualifiedType, "/") + fulltyp := pbFullyQualifiedType[idx+1:] // $pkgdirective.$typename + + // Replace package name of RequestType/ResponseType. + idx = strings.LastIndex(fulltyp, ".") + if idx <= 0 { + panic(fmt.Errorf("invalid type:%s", fulltyp)) + } + + typ := Camelcase(fulltyp[idx+1:]) + + // In case there are multiple pb files with the same package directive but different go_package, + // the mapping from package directive to go_package in nfd. + // Pkg2ValidGoPkg is incorrect and needs to be specific to the file name. + // However, the RequestType generated by jhump/protoreflect is in the form of ${package-directive}. + // RequestType without specifying the information about which pb file RequestType is defined in. + // + // The following approach is needed to locate the specific pb file where the message is defined: + // - Traverse all the messages and their definitions to find the pb file that matches the message name completely, + // and find the corresponding package for that pb file. + // - Rewrite the complete type of the request body. + rtype := pbFullyQualifiedType + if len(nfd.RPCMessageType) != 0 { + // Found the pb file where the message is defined. + pb, ok := nfd.RPCMessageType[pbFullyQualifiedType] + if !ok || len(pb) == 0 { + panic(fmt.Errorf("cannot find the protofile containing definition of %s", pbFullyQualifiedType)) + } + return rpcMessageTypeHandle(pb, typ, nfd) + } + return rtype +} + +func goFullyQualifiedType(pb, typ string, nfd *descriptor.FileDescriptor) string { + // Find the corresponding concrete type name based on the pb file. + validGoPkg, ok := nfd.Pb2ValidGoPkg[pb] + if !ok { + panic(fmt.Errorf("get valid gopkg of %s fail", pb)) + } + return validGoPkg + "." + typ +} + +func goFullyQualifiedTypeX(pb, typ string, nfd *descriptor.FileDescriptor) string { + // Find the corresponding concrete type name based on the pb file. + importPath, ok := nfd.Pb2ImportPath[pb] + if !ok { + panic(fmt.Errorf("get importPath of %s fail", pb)) + } + _, path := ExplodeImport(importPath) + // Defined and defined in dependent files. + for _, v := range nfd.ImportsX { + if v.Path != path { + continue + } + // rtype = v.Path + "." + typ + return v.Name + "." + typ + } + // Defined and defined in --protofile. + return nfd.BaseGoPackageName + "." + typ +} + +// ExplodeImport splits an import path into the importName and importPath. +func ExplodeImport(s string) (importName, importPath string) { + idx := strings.LastIndex(s, ";") + if idx != -1 { + importName = s[idx+1:] + importPath = s[:idx] + return PBGoPackage(importName), importPath + } + idx = strings.LastIndex(s, "/") + if idx != -1 { + importName = s[idx+1:] + importPath = s + return PBGoPackage(importName), importPath + } + return PBGoPackage(s), s +} + +// PBValidGoPackage returns a valid go package. +// +// Consider the scenario where option go_package="trpc.group/hello;world" is present. In this case, +// the importPath should be trpc.group/hello, but the importName should be world. +// +// In other words, referencing a type with hello.XXX is incorrect and world.XXX should be used instead. +func PBValidGoPackage(pkgName string) string { + var ( + pkg string + ) + idx := strings.LastIndex(pkgName, "/") + if idx < 0 { + pkg = pkgName + } else { + pkg = pkgName[idx+1:] + } + + pkg = strings.Replace(pkg, "-", "_", -1) + pkg = strings.Replace(pkg, ".", "_", -1) + + return TrimLeft(";", pkg) +} + +// Last returns the last element in `list` +func Last(list []string) string { + idx := len(list) - 1 + return list[idx] +} + +// HasPrefix test whether string `str` has prefix `prefix` +func HasPrefix(prefix, str string) bool { + return strings.HasPrefix(str, prefix) +} + +// HasSuffix test whether string `str` has suffix `suffix` +func HasSuffix(suffix, str string) bool { + return strings.HasSuffix(str, suffix) +} + +// Add adds two number. +func Add(num1, num2 int) int { + return num1 + num2 +} + +// LoadGoMod load the module name of current directory. +func LoadGoMod() (string, error) { + fin, err := openGoModFile() + if err != nil { + return "", err + } + sc := bufio.NewScanner(fin) + for sc.Scan() { + l := sc.Text() + if strings.HasPrefix(l, "module ") { + return strings.Split(l, " ")[1], nil + } + } + return "", nil +} + +func openGoModFile() (*os.File, error) { + d, err := os.Getwd() + if err != nil { + panic(err) + } + + p := filepath.Join(d, "go.mod") + _, err = os.Lstat(p) + if err != nil { + return nil, err + } + + return os.Open(p) +} + +// CheckSECVTpl checks whether the Validation feature is enabled to determine the exported template content. +func CheckSECVTpl(pkgMap map[string]string) bool { + if _, isKeyFound := pkgMap["validate"]; isKeyFound { + return true + } + if _, isKeyFound := pkgMap["trpc.v2.validate"]; isKeyFound { + return true + } + return false +} + +// Camelcase converts a string into camel case. +// Special cases must be compatible with existing protocols, otherwise they are converted to camel case naming. +func Camelcase(s string) string { + // Changes in camel case for existing protocols are not backward compatible. + // No changes are made to all uppercase letters. + + // The template expects message names to be in all capital letters and underscores, + // so we need to keep the original text. + if len(s) == 0 { + return s + } + + wordList := strings.Split(s, "_") + if len(wordList) == 1 { + if isAllUpper(wordList[0]) { + return s + } + return strcase.ToCamel(s) + } + + return CamelcaseList(wordList) +} + +// CamelcaseList converts a list of strings to camel case and returns the last string. +func CamelcaseList(wordList []string) string { + var camelWord string + for i := 0; i < len(wordList); i++ { + cur, seq := camelcaseListItem(wordList, i) + camelWord = fmt.Sprintf("%s%s%s", camelWord, cur, seq) + } + + return camelWord +} + +func camelcaseListItem(wordList []string, i int) (string, string) { + cur := wordList[i] + seq := getCamelcaseSeq(wordList, i, cur) + + if !isAllUpper(cur) { + cur = strcase.ToCamel(cur) + } + return cur, seq +} + +func getCamelcaseSeq(wordList []string, i int, cur string) string { + seq := "" + // If the current and the next word are both uppercase, they should be joined with an underscore. + if i != len(wordList)-1 && len(wordList[i+1]) != 0 { + curIsAllUpper := isAllUpper(cur) + nextIsAllUpper := isAllUpper(wordList[i+1]) + if curIsAllUpper || nextIsAllUpper { + seq = "_" + } + } + return seq +} + +// isAllUpper returns whether all the characters are uppercased or not. +func isAllUpper(s string) bool { + for _, c := range s { + if !unicode.IsUpper(c) { + return false + } + } + return true +} + +// Concat concats strings. +func Concat(sep string, s ...string) string { + ss := []string{} + ss = append(ss, s...) + return strings.Join(ss, sep) +} + +// MergeRPC combines RPCs and outputs the list. +func MergeRPC(v1 []*descriptor.RPCDescriptor, v2 []*descriptor.RPCDescriptor) []*descriptor.RPCDescriptor { + var result []*descriptor.RPCDescriptor + result = append(result, v1...) + result = append(result, v2...) + return result +} diff --git a/util/lang/lang_test.go b/util/lang/lang_test.go new file mode 100644 index 0000000..a8b35e4 --- /dev/null +++ b/util/lang/lang_test.go @@ -0,0 +1,230 @@ +package lang + +import ( + "errors" + "os" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/descriptor" +) + +func TestPBSimplifyGoType(t *testing.T) { + t.Run("case without dot", func(t *testing.T) { + require.Panics(t, func() { + PBSimplifyGoType("pkgname::typename", "pkgname") + }) + }) + + t.Run("case pkg == goPackageName", func(t *testing.T) { + p := PBSimplifyGoType("helloworld.HelloRequest", "helloworld") + require.Equal(t, "HelloRequest", p) + }) + + t.Run("case pkg != goPackageName", func(t *testing.T) { + p := PBSimplifyGoType("pkgname.typename", "pkgname") + require.Equal(t, "typename", p) + }) +} + +func TestPBGoType(t *testing.T) { + t.Run("case without dot", func(t *testing.T) { + require.Panics(t, func() { + PBGoType("typeWithoutDot") + }) + }) + + t.Run("case succ", func(t *testing.T) { + p := PBGoType("prefix/a.b.c.hello") + require.Equal(t, "prefixa_b_c.Hello", p) + }) +} + +func TestPBGoPackage(t *testing.T) { + require.Equal(t, "a_b_c", PBGoPackage("a.b.c")) + require.Equal(t, "a_b_c", PBGoPackage("prefix/a.b.c")) + require.Equal(t, "a_b_c", PBGoPackage("prefix/a-b-c")) + require.Equal(t, "a_b_c", PBGoPackage("a-b-c")) + require.Equal(t, "a_b_c", PBGoPackage("a.b-c")) +} + +func TestGoExport(t *testing.T) { + t.Run("case without dot", func(t *testing.T) { + typ := GoExport("test") + require.Equal(t, "Test", typ) + }) + + t.Run("case with dot", func(t *testing.T) { + typ := GoExport("test.test") + require.Equal(t, "test.Test", typ) + }) +} + +func TestSplitList(t *testing.T) { + vals := SplitList(",", "a,b,c") + require.Equal(t, []string{"a", "b", "c"}, vals) +} + +func TestTrimRight(t *testing.T) { + t.Run("case no split", func(t *testing.T) { + s := TrimRight(",", "test") + require.Equal(t, "test", s) + }) + + t.Run("case with split", func(t *testing.T) { + s := TrimRight(".", "test.go") + require.Equal(t, "test", s) + }) +} + +func TestTrimLeft(t *testing.T) { + s := TrimLeft(".", "test.go") + require.Equal(t, "go", s) +} + +func TestTitle(t *testing.T) { + s := Title("test") + require.Equal(t, "Test", s) +} + +func TestUnTitle(t *testing.T) { + s := UnTitle("TEst") + require.Equal(t, "tEst", s) +} + +func TestGoFullyQualifiedType(t *testing.T) { + t.Run("case invalid go type", func(t *testing.T) { + require.Panics(t, func() { + GoFullyQualifiedType("test/test", &descriptor.FileDescriptor{}) + }) + }) + + t.Run("case get pb empty", func(t *testing.T) { + fullTyp := "trpc.group/sample/helloworld.Request" + typ := GoFullyQualifiedType(fullTyp, &descriptor.FileDescriptor{}) + require.Equal(t, fullTyp, typ) + }) +} + +func TestPBValidGoPackage(t *testing.T) { + t.Run("case without /", func(t *testing.T) { + pkg := PBValidGoPackage("test.test") + require.Equal(t, "test_test", pkg) + }) + + t.Run("case with /", func(t *testing.T) { + pkg := PBValidGoPackage("test/test.test") + require.Equal(t, "test_test", pkg) + }) +} + +func TestLast(t *testing.T) { + ret := Last([]string{"a", "b", "c"}) + require.Equal(t, "c", ret) +} + +func TestHasPrefix(t *testing.T) { + has := HasPrefix("prefix", "prefix/test") + require.True(t, has) +} + +func TestHasSuffix(t *testing.T) { + has := HasSuffix("suffix", "test/suffix") + require.True(t, has) +} + +func TestAdd(t *testing.T) { + ret := Add(1, 2) + require.Equal(t, 3, ret) +} + +func TestLoadGoMod(t *testing.T) { + t.Run("case panic", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "", errors.New("fake error") + }) + defer p.Reset() + require.Panics(t, func() { + LoadGoMod() + }) + }) + + t.Run("case Lstat error", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd/", nil + }) + p.ApplyFunc(os.Lstat, func(name string) (os.FileInfo, error) { + return nil, errors.New("fake error") + }) + defer p.Reset() + mod, err := LoadGoMod() + require.Empty(t, mod) + require.NotNil(t, err) + }) + + t.Run("case open error", func(t *testing.T) { + p := gomonkey.NewPatches() + defer p.Reset() + p.ApplyFunc(os.Getwd, func() (dir string, err error) { + return "wd/", nil + }) + p.ApplyFunc(os.Lstat, func(name string) (os.FileInfo, error) { + return nil, nil + }) + p.ApplyFunc(os.Open, func(name string) (*os.File, error) { + return nil, errors.New("fake error") + }) + mod, err := LoadGoMod() + require.Empty(t, mod) + require.NotNil(t, err) + }) +} + +func TestCheckSECVTpl(t *testing.T) { + t.Run("case true", func(t *testing.T) { + ret := CheckSECVTpl(map[string]string{ + "validate": "exist", + }) + require.True(t, ret) + }) + + t.Run("case false", func(t *testing.T) { + ret := CheckSECVTpl(map[string]string{}) + require.False(t, ret) + }) +} + +func TestCamelcase(t *testing.T) { + t.Run("case empty", func(t *testing.T) { + ret := Camelcase("") + require.Empty(t, ret) + }) + + t.Run("case one word", func(t *testing.T) { + ret := Camelcase("TEST") + require.Equal(t, "TEST", ret) + ret = Camelcase("test") + require.Equal(t, "Test", ret) + }) + + t.Run("case multi words", func(t *testing.T) { + ret := Camelcase("test_test") + require.Equal(t, "TestTest", ret) + ret = Camelcase("test_ABC_ABC") + require.Equal(t, "Test_ABC_ABC", ret) + }) +} + +func Test_isAllUpper(t *testing.T) { + t.Run("case false", func(t *testing.T) { + ret := isAllUpper("Abc") + require.False(t, ret) + }) + + t.Run("case true", func(t *testing.T) { + ret := isAllUpper("ABC") + require.True(t, ret) + }) +} diff --git a/util/log/color.go b/util/log/color.go new file mode 100644 index 0000000..be2dd8f --- /dev/null +++ b/util/log/color.go @@ -0,0 +1,12 @@ +//go:build !windows +// +build !windows + +package log + +// Color directives. +const ( + ColorReset = "\033[0m" + ColorGreen = "\033[1;32m" + ColorRed = "\033[1;31m" + ColorPink = "\033[1;35m" +) diff --git a/util/log/color_windows.go b/util/log/color_windows.go new file mode 100644 index 0000000..6c48bc9 --- /dev/null +++ b/util/log/color_windows.go @@ -0,0 +1,11 @@ +//go:build windows +// +build windows + +package log + +const ( + ColorReset = "" + ColorGreen = "" + ColorRed = "" + ColorPink = "" +) diff --git a/util/log/log.go b/util/log/log.go new file mode 100644 index 0000000..5499bd9 --- /dev/null +++ b/util/log/log.go @@ -0,0 +1,72 @@ +// Package log encapsulates logging functionalities of the project. +package log + +import ( + "fmt" + "runtime" + "strings" +) + +var ( + logVerbose bool + logPrefix string +) + +// SetVerbose set logging level +func SetVerbose(verbose bool) { + logVerbose = verbose +} + +// SetPrefix set logging prefix +func SetPrefix(prefix string) { + logPrefix = prefix +} + +// Info print logging info at level INFO, if flag verbose true, filename and lineno will be logged. +func Info(format string, vals ...interface{}) { + fileno, _ := callerAddress(3) + if logVerbose { + fmt.Printf("%s%s[Info][%s] %s%s\n", ColorGreen, logPrefix, fileno, fmt.Sprintf(format, vals...), ColorReset) + } else { + fmt.Printf("%s%s %s%s\n", ColorGreen, logPrefix, fmt.Sprintf(format, vals...), ColorReset) + } +} + +// Debug print logging info at level DEBUG, if flag verbose true, filename and lineno will be logged. +func Debug(format string, vals ...interface{}) { + fileno, _ := callerAddress(3) + if logVerbose { + fmt.Printf("%s%s[Debug][%s] %s%s\n", ColorPink, logPrefix, fileno, fmt.Sprintf(format, vals...), ColorReset) + } +} + +// Error print logging info at level ERROR, if flag verbose true, filename and lineno will be logged. +func Error(format string, vals ...interface{}) { + fileno, _ := callerAddress(3) + if logVerbose { + fmt.Printf("%s%s[Error][%s] %s%s\n", ColorRed, logPrefix, fileno, fmt.Sprintf(format, vals...), ColorReset) + } else { + fmt.Printf("%s%s %s%s\n", ColorRed, logPrefix, fmt.Sprintf(format, vals...), ColorReset) + } +} + +// callerAddress skip N level to get the caller's filename and lineno, if no caller return error. +func callerAddress(skip int) (string, error) { + fpcs := make([]uintptr, 1) + // Skip N levels to get the caller + n := runtime.Callers(skip, fpcs) + if n == 0 { + return "", fmt.Errorf("MSG: NO CALLER") + } + + caller := runtime.FuncForPC(fpcs[0] - 1) + if caller == nil { + return "", fmt.Errorf("MSG: CALLER IS NIL") + } + + // Print the file name and line number + fileName, lineNo := caller.FileLine(fpcs[0] - 1) + baseName := fileName[strings.LastIndex(fileName, "/")+1:] + + return fmt.Sprintf("%s:%d", baseName, lineNo), nil +} diff --git a/util/log/log_test.go b/util/log/log_test.go new file mode 100644 index 0000000..a7dbc2f --- /dev/null +++ b/util/log/log_test.go @@ -0,0 +1,21 @@ +package log + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestInfo(t *testing.T) { + SetVerbose(true) + require.Equal(t, logVerbose, true) + Info("log content is: %s", "message") + Debug("log content is: %s", "message") + Error("log content is: %s", "message") + + SetVerbose(false) + require.Equal(t, logVerbose, false) + Info("log content is: %s", "message") + Debug("log content is: %s", "message") + Error("log content is: %s", "message") +} diff --git a/util/paths/trpc.go b/util/paths/trpc.go new file mode 100755 index 0000000..98fba47 --- /dev/null +++ b/util/paths/trpc.go @@ -0,0 +1,69 @@ +// Package paths provides functionality related to file paths within the project. +package paths + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/hashicorp/go-multierror" +) + +// Locate locates the directory of file name. It first searches in dirs and then in the template installation directory. +// name can be a regular file or directory. +func Locate(name string, search ...string) (string, error) { + // append user homedir + home, err := os.UserHomeDir() + if err != nil { + return "", err + } + trpcInstallUserPath := filepath.Join(home, ".trpc-cmdline-assets") + search = append(search, + ExpandTRPCSearch(trpcInstallUserPath)..., + ) + + for _, p := range search { + ap, e := filepath.Abs(p) + if e != nil { + err = multierror.Append(err, e).ErrorOrNil() + continue + } + + fp := filepath.Join(ap, name) + _, e = os.Lstat(fp) + if e != nil { + err = multierror.Append(err, e).ErrorOrNil() + continue + } + return ap, nil + } + return "", fmt.Errorf("%s not found in %s, errs: %w", name, strings.Join(search, ","), err) +} + +// ExpandTRPCSearch expands search path around installation path (typically ~/.trpc-cmdline-assets). +func ExpandTRPCSearch(installPath string) []string { + return []string{ + installPath, + filepath.Join(installPath, "submodules"), + filepath.Join(installPath, "submodules", "trpc-protocol"), + filepath.Join(installPath, "submodules", "trpc"), + filepath.Join(installPath, "submodules", "protoc-gen-secv"), + filepath.Join(installPath, "submodules", "protoc-gen-secv", "validate"), + filepath.Join(installPath, "trpc"), + filepath.Join(installPath, "protos"), + filepath.Join(installPath, "protos", "trpc"), + } +} + +// ExpandSearch expands search path around trpc_options.proto path. +func ExpandSearch(protoTRPCPath string) []string { // .trpc-cmdline-assets/submodules/trpc-protocol + parent := filepath.Dir(protoTRPCPath) // .trpc-cmdline-assets/submodules + grandParent := filepath.Dir(parent) // .trpc-cmdline-assets/ + return []string{ + parent, + grandParent, + filepath.Join(grandParent, "protos"), + protoTRPCPath, + } +} diff --git a/util/paths/trpc_test.go b/util/paths/trpc_test.go new file mode 100644 index 0000000..348214e --- /dev/null +++ b/util/paths/trpc_test.go @@ -0,0 +1,32 @@ +package paths + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestLocateProtoFile(t *testing.T) { + dir := filepath.Join(os.TempDir(), "paths.test_locate_protofile") + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + subdir := filepath.Join(dir, "files") + if err := os.MkdirAll(subdir, os.ModePerm); err != nil { + panic(err) + } + f, err := os.Create(filepath.Join(subdir, "trpcx.proto")) + if err != nil { + panic(err) + } + f.Close() + + // Files in the directory + p, err := Locate("trpcx.proto", subdir) + require.Nil(t, err) + require.Equal(t, subdir, p) +} diff --git a/util/pb/option.go b/util/pb/option.go new file mode 100644 index 0000000..7cae47a --- /dev/null +++ b/util/pb/option.go @@ -0,0 +1,39 @@ +package pb + +type options struct { + secvEnabled bool + pb2ImportPath map[string]string + pkg2ImportPath map[string]string + descriptorSetIn string +} + +// Option is used to store the content of the relevant options. +type Option func(*options) + +// WithSecvEnabled enables validation and generates stub code using protoc-gen-secv. +func WithSecvEnabled(enabled bool) Option { + return func(o *options) { + o.secvEnabled = enabled + } +} + +// WithPb2ImportPath adds mapping between pb file and import path. +func WithPb2ImportPath(m map[string]string) Option { + return func(o *options) { + o.pb2ImportPath = m + } +} + +// WithPkg2ImportPath adds the mapping between package name and import path. +func WithPkg2ImportPath(m map[string]string) Option { + return func(o *options) { + o.pkg2ImportPath = m + } +} + +// WithDescriptorSetIn adds the descriptor_set_in option to the command. +func WithDescriptorSetIn(descriptorSetIn string) Option { + return func(o *options) { + o.descriptorSetIn = descriptorSetIn + } +} diff --git a/util/pb/protoc.go b/util/pb/protoc.go new file mode 100644 index 0000000..5eaba83 --- /dev/null +++ b/util/pb/protoc.go @@ -0,0 +1,435 @@ +// Package pb encapsulates the protoc execution logic. +package pb + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "sort" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/util/fs" + "trpc.group/trpc-go/trpc-cmdline/util/log" + "trpc.group/trpc-go/trpc-cmdline/util/paths" +) + +// Constants definition. +const ( + ProtoTRPC = "trpc/proto/trpc_options.proto" + ProtoValidate = "trpc/validate/validate.proto" + ProtoSwagger = "trpc/swagger/swagger.proto" + + ProtoDir = "protobuf" + TrpcImportPrefix = "trpc/" +) + +// IsInternalProto tests if `fname` is internal. +func IsInternalProto(fname string) bool { + if strings.HasPrefix(fname, "google/protobuf") || + fname == ProtoTRPC || + fname == ProtoValidate || + fname == ProtoSwagger || + strings.HasPrefix(fname, TrpcImportPrefix) { + return true + } + return false +} + +// Protoc process `protofile` to generate *.pb.go, which is specified by `language` +// +// When using protoc, the following should also be taken into consideration: +// 1. The pb file being processed may import other pb files, e.g., a.proto imports b.proto, +// and the resulting a.pb.go file will call the initialization function in b.pb.go, +// typically named file_${path_to}b_proto_init(); +// 2. When executing protoc, the options passed can have an impact on the generated code. +// For instance, protoc -I path-to a.proto and protoc path-to/a.proto will generate different code, +// with the difference being reflected in the function name file${path_to}_b_proto_init(). +// The former will generate an empty ${path_to} part, leading to compilation failure. +// +// How to avoid this problem? +// - The import statements in pb files may contain virtual path information, +// which needs to be determined based on the search path specified with -I. +// - When processing pb files with protoc, the pb file names must contain virtual path information. +// For example, it should be protoc path-to/a.proto instead of protoc -I path-to a.proto. +// - Additionally, it is essential that there exists a search path in protoc's search path list +// that is the parent path of the pb file being processed. This is because of how protoc resolves paths. +// +// About the use of optional labels in proto syntax3: +// Compatibility logic needs to be implemented for different versions of protoc: +// - protoc (~, v3.12.0), pb syntax3 does not support optional labels +// - protoc [v3.12.0, v3.15.0), pb syntax3 supports optional labels, +// but the option --experimental_allow_proto3_optional needs to be added. +// - protoc v3.15.0+, optional labels in pb syntax3 syntax are parsed by default. +// +// ------------------------------------------------------------------------------------------------------------------ +// +// Regarding the issue of output paths for pb.go files: +// The paths=source_relative option controls the output filenames, not the import paths. +// The proto compiler associates an import path with each .proto file. When a.proto imports b.proto, +// the import path is used to determine what (if any) import statement to put in a.pb.go. You can set the import paths +// with go_package options in the .proto files, or with --go_opt=M= on the command line. +// +// The proto compiler generates a .pb.go file for each .proto file. There are several ways in which the output +// directory may be determined. For example, if source/a.proto has an import path of example.com/m/foo: +// +// --go_opt=paths=import: Import path; e.g., example.com/m/foo/a.pb.go +// --go_opt=paths=source_relative: Source path; e.g., source/a.pb.go +// --go_opt=module=example.com/m: Path relative to the module flag; e.g., foo/a.pb.go +// +// In the worst case, if none of these suit your needs, you can always generate into a temporary directory and copy the +// file into the desired location. Neither the paths nor module flags have any effect on the contents of the generated +// files. +func Protoc(protodirs []string, protofile, lang, outputdir string, opts ...Option) error { + options := options{ + pb2ImportPath: map[string]string{}, + pkg2ImportPath: map[string]string{}, + } + for _, o := range opts { + o(&options) + } + + protocArgs, err := genProtocArgs(protodirs, protofile, lang, outputdir, options) + if err != nil { + return fmt.Errorf("generate protoc args err: %w", err) + } + + importPath, ok := options.pb2ImportPath[protofile] + if ok { + defer movePbGoFile(protocArgs.argsGoOut, importPath, protocArgs.baseDir, protofile) + } + + var args []string + args = append(args, protocArgs.argsProtoPath...) + args = append(args, protocArgs.argsGoOut) + args = append(args, protofile) + if protocArgs.descriptorSetIn != "" { + args = append(args, protocArgs.descriptorSetIn) + } + + // pb3 supports "optional" and other labels. + args, err = makePb3Labels(args) + if err != nil { + panic(err) + } + + return execProtocCommand(args) +} + +func genRelPathFromWdWithDirs(protodirs []string, protofile, wd string) (string, error) { + for _, dir := range protodirs { + pbPath := filepath.Join(dir, protofile) + if fin, err := os.Lstat(pbPath); err != nil || fin.IsDir() { + // If there is an error getting file information or the path is a directory, + // continue searching for the next one. + continue + } + + rel, err := genRelPathFromWd(pbPath, wd) + if err != nil { + return "", err + } + + return rel, nil + } + return "", errors.New("no valid relative path found, please check if the file exists") +} + +func genRelPathFromWd(protofile, wd string) (string, error) { + absWd, err := filepath.Abs(wd) + if err != nil { + return "", fmt.Errorf("failed to obtain the absolute path for %s: %w", wd, err) + } + absPbFile, err := filepath.Abs(protofile) + if err != nil { + return "", fmt.Errorf("failed to obtain the absolute path for %s: %w", protofile, err) + } + relPath, err := filepath.Rel(absWd, absPbFile) + if err != nil { + log.Error("error getting the relative path from %s to %s", absWd, absPbFile) + return "", fmt.Errorf("Error getting the relative path: %w", err) + } + return relPath, nil +} + +func execProtocCommand(args []string) error { + log.Debug("protoc %s", strings.Join(args, " ")) + + cmd := exec.Command("protoc", args...) + if output, err := cmd.CombinedOutput(); err != nil { + msg := `Explicit 'optional' labels are disallowed in the Proto3 syntax` + str := strings.Join(cmd.Args, " ") + if strings.Contains(string(output), msg) { + return fmt.Errorf("run command: `%s`, error: %s...upgrade `protoc` to v3.15.0+", str, string(output)) + } + return fmt.Errorf("run command: `%s`, error: %s", str, string(output)) + } + + return nil +} + +type protocArgs struct { + baseDir string + argsProtoPath []string + argsGoOut string + descriptorSetIn string +} + +func genProtocArgs(protodirs []string, protofile, lang, outputdir string, options options) (*protocArgs, error) { + baseDir, baseName := filepath.Split(protofile) + outputdir = strings.TrimSuffix(filepath.Clean(outputdir), "/"+filepath.Clean(baseDir)) + + pb2ImportPath := options.pb2ImportPath + dirs, err := protoSearchDirs(pb2ImportPath) + if err != nil { + return nil, fmt.Errorf("proto search dirs err: %w", err) + } + protodirs = append(protodirs, dirs...) + + // make --go_out + argsGoOut := makeProtocOut(pb2ImportPath, lang, outputdir, options) + args := &protocArgs{baseDir, nil, argsGoOut, ""} + if options.descriptorSetIn == "" { // --proto_path and --descriptor_set_in cannot coexist. + p, err := paths.Locate(baseName, protodirs...) + if err != nil { + return nil, fmt.Errorf("paths locate err: %w", err) + } + p = strings.TrimSuffix(filepath.Clean(p), filepath.Clean(baseDir)) + // make --proto_path + args.argsProtoPath, err = makeProtoPath(protodirs, p, options) + if err != nil { + return nil, fmt.Errorf("make proto path err: %w", err) + } + return args, nil + } + args.descriptorSetIn = "--descriptor_set_in=" + options.descriptorSetIn + return args, nil +} + +func makePb3Labels(args []string) ([]string, error) { + // proto3 allow optional + v, err := protocVersion() + if err != nil { + return nil, err + } + if CheckVersion(v, "v3.15.0") { + // enabled by default, and no longer require --experimental_allow_proto3_optional flag + } else if CheckVersion(v, "v3.12.0") { + // [experimental] adding the "optional" field label, need passing --experimental_allow_proto3_optional flag + args = append(args, "--experimental_allow_proto3_optional") + } else if CheckVersion(v, "v3.6.0") { + // Not supported, no need for special settings. + } else { + // Not supported and version is below the recommended version of trpc. + log.Info("protoc version too low, please upgrade it") + } + return args, nil +} + +func movePbGoFile(argsGoOut, pkg, baseDir, protofile string) { + v := strings.Split(argsGoOut, ":") + if len(v) != 2 { + return + } + vv := strings.Split(v[1], "stub/") + if len(vv) != 2 { + return + } + if vv[1] == pkg { + pdir := filepath.Join(v[1], baseDir) + target := filepath.Join(pdir, fs.BaseNameWithoutExt(protofile)+".pb.go") + fs.Move(target, v[1]) + + idx := strings.Index(baseDir, "/") + if idx != -1 { + path := filepath.Join(v[1], baseDir[0:idx]) + os.RemoveAll(path) + } + } +} + +func protoSearchDirs(pb2ImportPath map[string]string) ([]string, error) { + var protodirs []string + var err error + + // locate trpc.proto + protodirs, err = trpcProtoSearchDir(pb2ImportPath, protodirs) + if err != nil { + return nil, err + } + + // locate validate.proto + protodirs, err = validateProtoSearchDir(pb2ImportPath, protodirs) + if err != nil { + return nil, err + } + + // locate protobuf dir + if isTrpcProtoImported(pb2ImportPath) { + pbDir, err := paths.Locate(ProtoDir) + if err == nil { + // If the trpc system pb directory is found, it is imported, otherwise it is skipped. + protodirs = append(protodirs, filepath.Join(pbDir, "protobuf")) + } + } + + return protodirs, nil +} + +func validateProtoSearchDir(pb2ImportPath map[string]string, protodirs []string) ([]string, error) { + _, secvdep := pb2ImportPath[ProtoValidate] + if secvdep { + secvp, err := paths.Locate(ProtoValidate) + if err != nil { + return nil, err + } + protodirs = append(protodirs, secvp) + } + return protodirs, nil +} + +func trpcProtoSearchDir(pb2ImportPath map[string]string, protodirs []string) ([]string, error) { + _, dep := pb2ImportPath[ProtoTRPC] + if dep { + p, err := paths.Locate(ProtoTRPC) + if err != nil { + return nil, err + } + protodirs = append(protodirs, p) + } + return protodirs, nil +} + +func isTrpcProtoImported(pbpkgMapping map[string]string) bool { + for k := range pbpkgMapping { + if strings.HasPrefix(k, TrpcImportPrefix) { + return true + } + } + + return false +} + +func makeProtocOut(pb2ImportPath map[string]string, language, outputdir string, options options) string { + pbpkg := genPbpkg(pb2ImportPath) + argsGoOut := makeProtocOutByLanguage(language, pbpkg, outputdir) + + if options.secvEnabled { + _, ok := options.pkg2ImportPath["validate"] + secvOut := "secv" + if !ok { + _, ok = options.pkg2ImportPath["trpc.v2.validate"] + secvOut = "secv-v2" + } + if ok { + argsGoOut = fixProtocOut(secvOut, argsGoOut, language) + } + } + return argsGoOut +} + +func makeProtocOutByLanguage(language string, pbpkg string, outputdir string) string { + languageToOut := map[string]string{ + "go": fmt.Sprintf("--%s_out=paths=source_relative%s:%s", language, pbpkg, outputdir), + } + + out := languageToOut[language] + if len(out) > 0 { + return out + } + + // Other unexpected programming languages. + _ = os.MkdirAll(outputdir, os.ModePerm) + if len(pbpkg) != 0 { + pbpkg += ":" + } + out = fmt.Sprintf("--%s_out=%s%s", language, pbpkg, outputdir) + return out +} + +func genPbpkg(pb2ImportPath map[string]string) string { + var pbpkg string + + if len(pb2ImportPath) != 0 { + for k, v := range pb2ImportPath { + + // 1. The official Google library should be left to protoc and protoc-gen-go to handle. + // 2. For other imported pb files, if they have the same validGoPkg as the protofile, + // then the package parsed by protoreflect/jhump for the pb file is empty. + // To solve the circular dependency problem here! + if strings.HasPrefix(k, "google/protobuf") || len(v) == 0 { + continue + } + //BUG: protoc-gen-go, https://google.golang.org/protobuf/issues/1151 + //if v == protofileValidGoPkg { + // v = "." + //} + //if v == protofileValidGoPkg { + // continue + //} + //pbpkg += ",M" + k + "=" + lang.PBValidGoPackage(v) + pbpkg += ",M" + k + "=" + v + } + } + return pbpkg +} + +func fixProtocOut(secvOut, protocOut, lang string) string { + new := fmt.Sprintf("--%s_out=lang=%s", secvOut, lang) + + vals := strings.SplitN(protocOut, "=", 2) + params := vals[1] + + switch lang { + case "go": + return new + "," + params + default: + return protocOut + } +} + +func makeProtoPath(protodirs []string, must string, options options) ([]string, error) { + protodirs = append(protodirs, must) + protodirs = fs.UniqFilePath(protodirs) + + args := []string{} + + // BUG protoc/protoc-gen-go + // see: https://github.com/golang/protobuf/issues/1252#issuecomment-741626261 + sort.Strings(protodirs) + + wd, _ := os.Getwd() + for pos, each := range protodirs { + if wd == each { + var newProtodirs []string + newProtodirs = append(newProtodirs, protodirs[0:pos]...) + newProtodirs = append(newProtodirs, protodirs[pos+1:]...) + newProtodirs = append(newProtodirs, wd) + protodirs = newProtodirs + break + } + } + + return genProtoPathArgs(protodirs, args) +} + +func genProtoPathArgs(protodirs []string, args []string) ([]string, error) { + //for _, protodir := range protodirs { + for i := len(protodirs) - 1; i >= 0; i-- { + protodir := protodirs[i] + protodir, err := filepath.Abs(protodir) + if err != nil { + continue + } + + // filter out non-existing directories. + fin, err := os.Lstat(protodir) + if err != nil || !fin.IsDir() { + continue + } + + args = append(args, fmt.Sprintf("--proto_path=%s", protodir)) + } + return args, nil +} diff --git a/util/pb/protoc_test.go b/util/pb/protoc_test.go new file mode 100644 index 0000000..7f23903 --- /dev/null +++ b/util/pb/protoc_test.go @@ -0,0 +1,300 @@ +package pb + +import ( + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/agiledragon/gomonkey" + + "trpc.group/trpc-go/trpc-cmdline/config" +) + +var wd string + +func TestMain(m *testing.M) { + if _, err := config.Init(); err != nil { + panic(err) + } + if err := setup(); err != nil { + panic(err) + } + + d, err := os.Getwd() + if err != nil { + panic(err) + } + wd = filepath.Join(d, "testcase") + + os.Exit(m.Run()) +} + +func TestProtoc(t *testing.T) { + languages := []string{"go"} + outputdir := filepath.Join(wd, "generated") + os.Mkdir(outputdir, os.ModePerm) + defer os.RemoveAll(outputdir) + + type args struct { + protodirs []string + protofile string + pb2impt map[string]string + } + + tests := []struct { + name string + args args + }{ + { + "case1", + args{ + []string{wd}, + "helloworld.proto", + nil, + }, + }, + { + "case2", + args{ + []string{wd}, + "helloworld.proto", + map[string]string{"helloworld.proto": "trpc.group/examples/helloworld"}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + for _, lang := range languages { + err := Protoc(tt.args.protodirs, tt.args.protofile, lang, outputdir, WithPb2ImportPath(tt.args.pb2impt)) + if err != nil { + t.Errorf("Protoc() error = %v", err) + } + } + }) + } + + // clean + os.RemoveAll(outputdir) +} + +func Test_makeProtocOutByLanguage(t *testing.T) { + type args struct { + language string + pbpkg string + outputdir string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "case_other_language", + args: args{ + language: "other", + pbpkg: "pbpkg", + outputdir: "outputdir", + }, + want: "--other_out=pbpkg:outputdir", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc(os.MkdirAll, func(path string, perm os.FileMode) error { + return nil + }) + defer p.Reset() + + if got := makeProtocOutByLanguage(tt.args.language, tt.args.pbpkg, tt.args.outputdir); got != tt.want { + t.Errorf("makeProtocOutByLanguage() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_genRelPathFromWd(t *testing.T) { + type args struct { + wd string + protofile string + } + tests := []struct { + name string + args args + want string + wantErr bool + absRsp map[string]string + absErr map[string]error + }{ + { + name: "get wd abs path error", + args: args{ + wd: "wd", + protofile: "protofile", + }, + want: "", + wantErr: true, + absRsp: map[string]string{}, + absErr: map[string]error{ + "wd": fmt.Errorf("error"), + }, + }, + { + name: "get protofile abs path error", + args: args{ + wd: "wd", + protofile: "protofile", + }, + want: "", + wantErr: true, + absRsp: map[string]string{}, + absErr: map[string]error{ + "protofile": fmt.Errorf("error"), + }, + }, + { + name: "gen ref path error", + args: args{ + wd: "wd", + protofile: "protofile", + }, + want: "", + wantErr: true, + absRsp: map[string]string{ + "wd": "/wd", + "protofile": "a/protofile", + }, + absErr: map[string]error{}, + }, + { + name: "gen ref path succ", + args: args{ + wd: "wd", + protofile: "protofile", + }, + want: "a/protofile", + wantErr: false, + absRsp: map[string]string{ + "wd": "/wd", + "protofile": "/wd/a/protofile", + }, + absErr: map[string]error{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc(filepath.Abs, func(path string) (string, error) { + return tt.absRsp[path], tt.absErr[path] + }) + defer p.Reset() + + got, err := genRelPathFromWd(tt.args.protofile, tt.args.wd) + if (err != nil) != tt.wantErr { + t.Errorf("genRelPathFromWd() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("genRelPathFromWd() got = %v, want %v", got, tt.want) + } + }) + } +} + +type mockFileInfo struct { + err error + isDir bool +} + +func (s *mockFileInfo) Name() string { return "" } +func (s *mockFileInfo) Size() int64 { return 0 } +func (s *mockFileInfo) Mode() os.FileMode { return 0 } +func (s *mockFileInfo) ModTime() time.Time { return time.Time{} } +func (s *mockFileInfo) IsDir() bool { return s.isDir } +func (s *mockFileInfo) Sys() interface{} { return nil } + +func Test_genRelPathFromWdWithDirs(t *testing.T) { + type args struct { + protodirs []string + protofile string + wd string + } + tests := []struct { + name string + args args + want string + wantErr bool + lstatErr error + isDir bool + genRelPathFromWdRsp string + genRelPathFromWdErr error + }{ + { + name: "os.Lstat error", + args: args{ + protodirs: []string{"dir1"}, + protofile: "file", + wd: "path", + }, + want: "", + wantErr: true, + lstatErr: fmt.Errorf("error"), + }, + { + name: "genRelPathFromWd error", + args: args{ + protodirs: []string{"dir1"}, + protofile: "file", + wd: "path", + }, + want: "", + wantErr: true, + isDir: false, + genRelPathFromWdRsp: "path", + genRelPathFromWdErr: fmt.Errorf("error"), + }, + { + name: "genRelPathFromWd succ", + args: args{ + protodirs: []string{"dir1"}, + protofile: "file", + wd: "path", + }, + want: "path", + wantErr: false, + isDir: false, + genRelPathFromWdRsp: "path", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p := gomonkey.ApplyFunc(os.Lstat, func(name string) (os.FileInfo, error) { + return &mockFileInfo{isDir: tt.isDir}, tt.lstatErr + }) + defer p.Reset() + p.ApplyFunc(genRelPathFromWd, func(protofile, wd string) (string, error) { + return tt.genRelPathFromWdRsp, tt.genRelPathFromWdErr + }) + + got, err := genRelPathFromWdWithDirs(tt.args.protodirs, tt.args.protofile, tt.args.wd) + if (err != nil) != tt.wantErr { + t.Errorf("genRelPathFromWdWithDirs() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("genRelPathFromWdWithDirs() got = %v, want %v", got, tt.want) + } + }) + } +} + +func setup() error { + if _, err := config.Init(); err != nil { + return err + } + deps, err := config.LoadDependencies() + if err != nil { + return err + } + return config.SetupDependencies(deps) +} diff --git a/util/pb/protoc_version.go b/util/pb/protoc_version.go new file mode 100644 index 0000000..b7cd937 --- /dev/null +++ b/util/pb/protoc_version.go @@ -0,0 +1,84 @@ +package pb + +import ( + "fmt" + "os/exec" + "strconv" + "strings" +) + +func protocVersion() (version string, err error) { + // check installed or not + _, err = exec.LookPath("protoc") + if err != nil { + return "", fmt.Errorf("protoc not found, %v", err) + } + + // print version + cmd := exec.Command("protoc", "--version") + output, err := cmd.CombinedOutput() + if err != nil { + return + } + + version = strings.TrimPrefix(strings.TrimSpace(string(output)), "libprotoc ") + return +} + +const ( + requireProtoVersion = "v3.6.0" +) + +func isOldProtocVersion() (old bool, err error) { + version, err := protocVersion() + if err != nil { + return + } + return oldVersion(version) +} + +func oldVersion(version string) (old bool, err error) { + return !CheckVersion(version, requireProtoVersion), nil +} + +// CheckVersion check if version meet the requirement +func CheckVersion(version, required string) bool { + + version = getVersion(version) + required = getVersion(required) + + m1, n1, r1 := semanticVersion(version) + m2, n2, r2 := semanticVersion(required) + + if !(m1 >= m2 && n1 >= n2 && r1 >= r2) { + return false + } + return true +} + +func getVersion(version string) string { + if len(version) != 0 && (version[0] == 'v' || version[0] == 'V') { + version = version[1:] + } + return version +} + +// semanticVersion extract the major, minor and revision (patching) version +func semanticVersion(ver string) (major, minor, revision int) { + vv := strings.Split(ver, ".") + + resultList := make([]int, 3) + for i := 0; i < len(resultList) && i < len(vv); i++ { + num, err := strconv.Atoi(vv[i]) + if err != nil { + break + } + resultList[i] = num + } + + major = resultList[0] + minor = resultList[1] + revision = resultList[2] + + return +} diff --git a/util/pb/protoc_version_test.go b/util/pb/protoc_version_test.go new file mode 100644 index 0000000..b219e9e --- /dev/null +++ b/util/pb/protoc_version_test.go @@ -0,0 +1,161 @@ +package pb + +import ( + "errors" + "os/exec" + "reflect" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" +) + +func Test_oldVersion(t *testing.T) { + type args struct { + version string + } + tests := []struct { + name string + args args + wantOld bool + }{ + {"protoc-2.5.0", args{version: "2.5.0"}, true}, + {"protoc-2.6.0", args{version: "2.6.0"}, true}, + {"protoc-2.7.0", args{version: "2.7.0"}, true}, + {"protoc-3.5.0", args{version: "3.5.0"}, true}, + {"protoc-3.6.0", args{version: "3.6.0"}, false}, + {"protoc-3.6.1", args{version: "3.6.1"}, false}, + {"protoc-3.7.0", args{version: "3.7.0"}, false}, + {"protoc-3.7.1", args{version: "3.7.1"}, false}, + {"protoc-3.10.1", args{version: "3.10.1"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotOld, err := oldVersion(tt.args.version) + if err != nil { + t.Errorf("judge protoc version error = %v", err) + } + if gotOld != tt.wantOld { + t.Errorf("oldVersion() gotOld = %v, want %v", gotOld, tt.wantOld) + } + }) + } +} + +func Test_isOldProtocVersion(t *testing.T) { + t.Run("return version 3.15.0", func(t *testing.T) { + p := gomonkey.ApplyFunc(protocVersion, func() (string, error) { + return "3.15.0", nil + }) + defer p.Reset() + old, err := isOldProtocVersion() + require.Nil(t, err) + require.False(t, old) + }) + + t.Run("return version 2.5.0", func(t *testing.T) { + p := gomonkey.ApplyFunc(protocVersion, func() (string, error) { + return "2.5.0", nil + }) + defer p.Reset() + old, err := isOldProtocVersion() + require.Nil(t, err) + require.True(t, old) + }) + + t.Run("return version err", func(t *testing.T) { + p := gomonkey.ApplyFunc(protocVersion, func() (string, error) { + return "", errors.New("unexpected error") + }) + defer p.Reset() + _, err := isOldProtocVersion() + require.NotNil(t, err) + }) + + t.Run("return version v2.5.0", func(t *testing.T) { + p := gomonkey.ApplyFunc(protocVersion, func() (string, error) { + return "v2.5.0", nil + }) + defer p.Reset() + old, err := isOldProtocVersion() + require.Nil(t, err) + require.True(t, old) + }) +} + +func Test_protocVersion(t *testing.T) { + t.Run("protoc not existed", func(t *testing.T) { + p := gomonkey.ApplyFunc(exec.LookPath, func(p string) (string, error) { + return "", errors.New("not found") + }) + defer p.Reset() + + v, err := protocVersion() + require.NotNil(t, err) + require.Empty(t, v) + }) + + t.Run("protoc run", func(t *testing.T) { + + p := gomonkey.NewPatches() + p.ApplyFunc(exec.LookPath, func(p string) (string, error) { + return p, nil + }) + defer p.Reset() + + t.Run("!success", func(t *testing.T) { + cmd := &exec.Cmd{} + p := gomonkey.ApplyMethod(reflect.TypeOf(cmd), "CombinedOutput", func(*exec.Cmd) ([]byte, error) { + return nil, errors.New("permission denied") + }) + defer p.Reset() + + v, err := protocVersion() + require.NotNil(t, err) + require.Empty(t, v) + }) + + t.Run("success", func(t *testing.T) { + cmd := &exec.Cmd{} + p := gomonkey.ApplyMethod(reflect.TypeOf(cmd), "CombinedOutput", func(*exec.Cmd) ([]byte, error) { + return []byte("libprotoc 3.15.6"), nil + }) + defer p.Reset() + + v, err := protocVersion() + require.Nil(t, err) + require.Equal(t, v, "3.15.6") + }) + }) + +} + +func Test_semanticVersion(t *testing.T) { + t.Run("2.5.0 ok", func(t *testing.T) { + a, b, c := semanticVersion("2.5.0") + require.Equal(t, 2, a) + require.Equal(t, 5, b) + require.Equal(t, 0, c) + }) + + t.Run("2.5.z ok", func(t *testing.T) { + a, b, c := semanticVersion("2.5.z") + require.Equal(t, 2, a) + require.Equal(t, 5, b) + require.Equal(t, 0, c) + }) + + t.Run("2.5 ok", func(t *testing.T) { + a, b, c := semanticVersion("2.5") + require.Equal(t, 2, a) + require.Equal(t, 5, b) + require.Equal(t, 0, c) + }) + + t.Run("2 ok", func(t *testing.T) { + a, b, c := semanticVersion("2") + require.Equal(t, 2, a) + require.Equal(t, 0, b) + require.Equal(t, 0, c) + }) +} diff --git a/util/pb/testcase/helloworld-import-trpc.proto b/util/pb/testcase/helloworld-import-trpc.proto new file mode 100644 index 0000000..3329cf5 --- /dev/null +++ b/util/pb/testcase/helloworld-import-trpc.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +import "trpc/proto/trpc_options.proto"; + +message HelloReq{} +message HelloRsp{} + +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp) {option (trpc.alias) = "/AnotherRpcName"; }; +} diff --git a/util/pb/testcase/helloworld.proto b/util/pb/testcase/helloworld.proto new file mode 100644 index 0000000..fd08976 --- /dev/null +++ b/util/pb/testcase/helloworld.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; +package helloworld; + +option go_package="trpc.group/examples/helloworld"; + +message HelloReq{} +message HelloRsp{} + +service helloworld_svr { + rpc Hello(HelloReq) returns(HelloRsp); +} diff --git a/util/promptui/promptui.go b/util/promptui/promptui.go new file mode 100644 index 0000000..af30ac3 --- /dev/null +++ b/util/promptui/promptui.go @@ -0,0 +1,64 @@ +// Package promptui provides interactive prompts for command-line applications. +package promptui + +import ( + "errors" + "fmt" + "strings" + + "github.com/manifoldco/promptui" +) + +// WithMinLength limits the minimum input length. +func WithMinLength(minlen int) promptui.ValidateFunc { + return func(input string) error { + input = strings.TrimSpace(input) + if minlen < 0 { + return nil + } + vv := []rune(input) + if len(vv) < minlen { + return fmt.Errorf("title must at least %d chars", minlen) + } + return nil + } +} + +// Read reads from standard input, specifies the label, the validateFunc, and returns the string. +func Read(label string, validateFunc promptui.ValidateFunc) (string, error) { + + prompt := promptui.Prompt{ + Label: label, + Default: "", + AllowEdit: true, + Validate: validateFunc, + Mask: 0, + HideEntered: false, + IsVimMode: false, + } + + result, err := prompt.Run() + + if err != nil { + fmt.Printf("Prompt failed %v\n", err) + return "", err + } + return result, nil +} + +// ConfirmQuit reads user input to determine whether to quit. +func ConfirmQuit() bool { + c, err := Read("press q to quit", func(s string) error { + if len(s) != 0 && len(s) != 1 { + return errors.New("invalid input") + } + return nil + }) + if err != nil { + return false + } + if c == "q" { + return true + } + return false +} diff --git a/util/semver/semver.go b/util/semver/semver.go new file mode 100644 index 0000000..78601ef --- /dev/null +++ b/util/semver/semver.go @@ -0,0 +1,47 @@ +// Package semver is a library for parsing tool versions. +package semver + +import ( + "regexp" + "strconv" +) + +const versionPattern = "(0|(?:[1-9]\\d*))(?:\\.(0|(?:[1-9]\\d*))(?:\\.(0|(?:[1-9]\\d*)))?(?:\\-([\\w][\\w\\.\\-_]*))?)?" + +var versionRE = regexp.MustCompile(versionPattern) + +// Versions extract the major, minor and revision (patching) version +func Versions(ver string) (major, minor, revision int) { + var err error + matches := versionRE.FindStringSubmatch(ver) + + if len(matches) >= 2 { + major, err = strconv.Atoi(matches[1]) + if err != nil { + return + } + } + + if len(matches) >= 3 { + minor, err = strconv.Atoi(matches[2]) + if err != nil { + return + } + } + + if len(matches) >= 4 { + revision, err = strconv.Atoi(matches[3]) + if err != nil { + return + } + } + return +} + +// NewerThan check whether semver `v1` is newer than `v2` or not. +func NewerThan(v1 string, v2 string) bool { + m1, n1, r1 := Versions(v1) + m2, n2, r2 := Versions(v2) + + return (m1 > m2) || (m1 == m2 && n1 > n2) || (m1 == m2 && n1 == n2 && r1 > r2) +} diff --git a/util/semver/semver_test.go b/util/semver/semver_test.go new file mode 100644 index 0000000..7bdd327 --- /dev/null +++ b/util/semver/semver_test.go @@ -0,0 +1,63 @@ +package semver + +import "testing" + +func TestNewerThan(t *testing.T) { + type args struct { + v1 string + v2 string + } + tests := []struct { + name string + args args + want bool + }{ + {"1.0.0 vs 1.0.0", args{"1.0.0", "1.0.0"}, false}, + {"1.0.0 vs 1.0.1", args{"1.0.0", "1.0.1"}, false}, + {"1.0.0 vs 1.1.0", args{"1.0.0", "1.1.0"}, false}, + {"1.0.0 vs 1.1.1", args{"1.0.0", "1.1.1"}, false}, + {"2.0.0 vs 1.0.0", args{"2.0.0", "1.0.0"}, true}, + {"2.0.0 vs 1.0.1", args{"2.0.0", "1.0.1"}, true}, + {"2.0.0 vs 1.1.0", args{"2.0.0", "1.1.0"}, true}, + {"2.0.0 vs 1.1.1", args{"2.0.0", "1.1.1"}, true}, + {"2.5.0 vs 2.6.0", args{"2.5.0", "2.6.0"}, false}, + {"2.5.0 vs 2.6.1", args{"2.5.0", "2.6.1"}, false}, + {"2.5.1 vs 2.5.1", args{"2.5.1", "2.5.1"}, false}, + {"2.6.0 vs 2.6.0", args{"2.6.0", "2.6.0"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewerThan(tt.args.v1, tt.args.v2); got != tt.want { + t.Errorf("NewerThan() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestVersions(t *testing.T) { + tests := []struct { + name string + ver string + wantMajor int + wantMinor int + wantRevision int + }{ + {"v1.2.3-dev", "v1.2.3-dev", 1, 2, 3}, + {"1.2.3-dev", "1.2.3-dev", 1, 2, 3}, + {"1.2.3", "1.2.3", 1, 2, 3}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotMajor, gotMinor, gotRevision := Versions(tt.ver) + if gotMajor != tt.wantMajor { + t.Errorf("Versions() gotMajor = %v, want %v", gotMajor, tt.wantMajor) + } + if gotMinor != tt.wantMinor { + t.Errorf("Versions() gotMinor = %v, want %v", gotMinor, tt.wantMinor) + } + if gotRevision != tt.wantRevision { + t.Errorf("Versions() gotRevision = %v, want %v", gotRevision, tt.wantRevision) + } + }) + } +} diff --git a/util/style/gofmt.go b/util/style/gofmt.go new file mode 100644 index 0000000..c435bb9 --- /dev/null +++ b/util/style/gofmt.go @@ -0,0 +1,53 @@ +// Package style provides formatting functions. +package style + +import ( + "fmt" + "go/format" + "os" + "path/filepath" + "strings" + + "trpc.group/trpc-go/trpc-cmdline/util/log" +) + +// Format the code in place. +func Format(fpath string, lang string) error { + switch lang { + case "go": + return GoFmt(fpath) + default: + return nil + } +} + +// GoFmt formats go code in place. +func GoFmt(fpath string) error { + fin, err := os.ReadFile(fpath) + if err != nil { + return err + } + + buf, err := format.Source(fin) + if err != nil { + return fmt.Errorf("format error: %v", err) + } + return os.WriteFile(fpath, buf, 0644) +} + +// GoFmtDir formats Go code in-place in a directory. +func GoFmtDir(dir string) error { + err := filepath.Walk(dir, func(fpath string, info os.FileInfo, err error) error { + if strings.HasSuffix(fpath, ".go") && !info.IsDir() { + err := GoFmt(fpath) + if err != nil { + log.Error("Warn: style file:%s error:%v", fpath, err) + } + } + if info.IsDir() && dir != fpath { + return GoFmtDir(fpath) + } + return nil + }) + return err +} diff --git a/util/style/gofmt_test.go b/util/style/gofmt_test.go new file mode 100644 index 0000000..4d8f753 --- /dev/null +++ b/util/style/gofmt_test.go @@ -0,0 +1,118 @@ +package style_test + +import ( + "errors" + "go/format" + "os" + "path/filepath" + "testing" + + "github.com/agiledragon/gomonkey" + "github.com/stretchr/testify/require" + + "trpc.group/trpc-go/trpc-cmdline/util/style" +) + +var sourceRaw = `package main + +func main() { +fmt.Println("hello world") + fmt.Println("Hello world") +fmt.Println("hello world") +return +} +` + +var sourceFormatted = `package main + +func main() { + fmt.Println("hello world") + fmt.Println("Hello world") + fmt.Println("hello world") + return +} +` + +func TestFormat(t *testing.T) { + + t.Run("format go", func(t *testing.T) { + var err error + // setup + dir := filepath.Join(os.TempDir(), "gofmt") + if err = os.MkdirAll(dir, os.ModePerm); err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + fp := filepath.Join(dir, "sourceRaw.go") + if err = os.WriteFile(fp, []byte(sourceRaw), 0666); err != nil { + panic(err) + } + + // format + if err = style.Format(fp, "go"); err != nil { + t.Fatal(err) + } + + // validate + var buf []byte + if buf, err = os.ReadFile(fp); err != nil { + panic(err) + } + require.Equal(t, string(buf), sourceFormatted) + }) + + t.Run("format !go", func(t *testing.T) { + err := style.Format("fpath", "other") + require.Nil(t, err) + }) +} + +func TestGoFmt_Exception(t *testing.T) { + + t.Run("GoFmt (ReadFile error)", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.ReadFile, func(string) ([]byte, error) { + return nil, errors.New("read file error") + }) + defer p.Reset() + err := style.GoFmt("fpath") + require.NotNil(t, err) + }) + + t.Run("GoFmt (Source error)", func(t *testing.T) { + p := gomonkey.ApplyFunc(os.ReadFile, func(string) ([]byte, error) { + return nil, nil + }) + p.ApplyFunc(format.Source, func(src []byte) ([]byte, error) { + return nil, errors.New("source error") + }) + defer p.Reset() + err := style.GoFmt("fpath") + require.NotNil(t, err) + }) + + t.Run("GoFmt (WriteFile error)", func(t *testing.T) { + p := gomonkey.NewPatches() + p.ApplyFunc(os.ReadFile, func(filename string) ([]byte, error) { + return nil, nil + }) + p.ApplyFunc(format.Source, func(src []byte) ([]byte, error) { + return nil, nil + }) + p.ApplyFunc(os.WriteFile, func(filename string, data []byte, perm os.FileMode) error { + return errors.New("fake error") + }) + defer p.Reset() + err := style.GoFmt("fpath") + require.NotNil(t, err) + }) +} + +func TestGoFmtDir(t *testing.T) { + p := gomonkey.ApplyFunc(style.GoFmt, func(string) error { + return nil + }) + defer p.Reset() + err := style.GoFmtDir("./") + require.Nil(t, err) +}