[
  {
    "path": ".github/workflows/game-2048-kubescape.yaml",
    "content": "name: Game 2048 Kubescape CI/CD Example\n\non:\n  # push:\n  #   branches: [ master ]\n  # pull_request:\n  #   branches: [ master ]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n    inputs:\n      kubescape_fail_threshold:\n        description: \"Sets fail threshold for Kubescape\"\n        required: true\n        default: \"30\"\n\nenv:\n  ENVIRONMENT: \"dev\"\n  PROJECT_DIR: \"game-2048-example\"\n  PROJECT_NAME: \"game-2048\"\n  KUBESCAPE_FAIL_THRESHOLD: 30\n\njobs:\n  build-and-test-application:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: npm install, build, and test\n        run: |\n          npm install\n          npm run build --if-present\n          npm test\n        working-directory: ${{ env.PROJECT_DIR }}\n\n  kubescape-nsa-security-check:\n    runs-on: ubuntu-latest\n    needs: build-and-test-application\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install Kubescape\n        run: curl -s https://raw.githubusercontent.com/armosec/kubescape/master/install.sh | /bin/bash\n\n      - name: Scan Kubernetes YAML files\n        run: |\n          kubescape scan framework nsa kustomize/ \\\n            -t ${{ github.event.inputs.kubescape_fail_threshold || env.KUBESCAPE_FAIL_THRESHOLD }} \\\n            --submit --account=${{ secrets.ARMOSEC_PORTAL_ACCOUNT_ID }}\n        working-directory: ${{ env.PROJECT_DIR }}\n\n      - name: Notify using Slack about Kubescape Scan Issues\n        if: ${{ always() }}\n        uses: 8398a7/action-slack@v3\n        with:\n          status: custom\n          fields: workflow,job,commit,repo,ref,author,took\n          custom_payload: |\n            {\n              attachments: [\n              {\n                color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',\n                text:`\n                  ${process.env.AS_WORKFLOW}\\n\n                  *Environment*: ${process.env.ENVIRONMENT}\\n\n                  *Job:* ${process.env.AS_JOB}\\n\n                  *Commit:* (${process.env.AS_COMMIT})\\n\n                  *Repo:* ${process.env.AS_REPO}\\n\n                  *Ref:* ${process.env.AS_REF}\\n\n                  *Author:* ${process.env.AS_AUTHOR}\\n\n                  *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\\n\n                  *Kubescape scan results:* https://cloud.armosec.io/repositories-scan/\n                `,\n              }]\n            }\n        env:\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n\n  build-and-push-app-image:\n    runs-on: ubuntu-latest\n    needs: kubescape-nsa-security-check\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Log in to DigitalOcean Container Registry with short-lived credentials\n        run: doctl registry login --expiry-seconds 600\n\n      - name: Push App Image to DigitalOcean Container Registry\n        uses: docker/build-push-action@v3\n        with:\n          context: ${{ env.PROJECT_DIR }}\n          push: true\n          tags: \"${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}\"\n\n  deploy-to-k8s:\n    runs-on: ubuntu-latest\n    needs: build-and-push-app-image\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Install kubectl\n        uses: azure/setup-kubectl@v3\n\n      - name: Configure kubectl\n        run: |\n          doctl kubernetes cluster kubeconfig save ${{ secrets.DOKS_CLUSTER }} --expiry-seconds 600\n\n      - name: Configure app deployment registry\n        run: |\n          DOCKER_IMAGE=\"${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}\"\n          sed -i \"s#image:.*#image: ${DOCKER_IMAGE}#g\" deployment.yaml\n        working-directory: ${{ env.PROJECT_DIR }}/kustomize/resources/\n\n      - name: Deploy app to Kubernetes\n        run: kubectl apply --prune --all -k kustomize/\n        working-directory: ${{ env.PROJECT_DIR }}\n"
  },
  {
    "path": ".github/workflows/game-2048-snyk.yaml",
    "content": "name: Game 2048 Snyk CI/CD Example\n\non:\n  # push:\n  #   branches: [ master ]\n  # pull_request:\n  #   branches: [ master ]\n\n  # Allows you to run this workflow manually from the Actions tab\n  workflow_dispatch:\n    inputs:\n      snyk_fail_threshold:\n        description: |\n          Sets fail threshold for Snyk \n          (low | medium | high | critical)\n        required: true\n        default: \"medium\"\n\nenv:\n  ENVIRONMENT: \"dev\"\n  PROJECT_DIR: \"game-2048-example\"\n  PROJECT_NAME: \"game-2048\"\n  SNYK_FAIL_THRESHOLD: \"medium\"\n\njobs:\n  build-and-test-application:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: npm install, build, and test\n        run: |\n          npm install\n          npm run build --if-present\n          npm test\n        working-directory: ${{ env.PROJECT_DIR }}\n\n  snyk-container-security-check:\n    runs-on: ubuntu-latest\n    needs: build-and-test-application\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Build App Image for Snyk container scanning\n        uses: docker/build-push-action@v3\n        with:\n          context: ${{ env.PROJECT_DIR }}\n          push: false\n          tags: \"${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}\"\n\n      - name: Install Snyk\n        uses: snyk/actions/setup@master\n\n      - name: Check application container vulnerabilities\n        run: |\n          snyk container test \"${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}\" \\\n            --file=${{ env.PROJECT_DIR }}/Dockerfile \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --target-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=${{ env.ENVIRONMENT }} \\\n            --sarif-file-output=snyk-container-scan.sarif\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n\n      - name: Upload Snyk report SARIF file\n        if: ${{ always() }}\n        uses: github/codeql-action/upload-sarif@v2\n        with:\n          sarif_file: snyk-container-scan.sarif\n          category: snyk-container-scan\n          \n      - name: Notify using Slack about Snyk Scan Issues\n        if: ${{ always() }}\n        uses: 8398a7/action-slack@v3\n        with:\n          status: custom\n          fields: workflow,job,commit,repo,ref,author,took\n          custom_payload: |\n            {\n              attachments: [\n              {\n                color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',\n                text:`\n                  ${process.env.AS_WORKFLOW}\\n\n                  *Environment*: ${process.env.ENVIRONMENT}\\n\n                  *Job:* ${process.env.AS_JOB}\\n\n                  *Commit:* (${process.env.AS_COMMIT})\\n\n                  *Repo:* ${process.env.AS_REPO}\\n\n                  *Ref:* ${process.env.AS_REF}\\n\n                  *Author:* ${process.env.AS_AUTHOR}\\n\n                  *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\\n\n                  *Snyk scan results:* https://app.snyk.io\n                `,\n              }]\n            }\n        env:\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n\n  build-and-push-app-image:\n    runs-on: ubuntu-latest\n    needs: snyk-container-security-check\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Log in to DigitalOcean Container Registry with short-lived credentials\n        run: doctl registry login --expiry-seconds 600\n\n      - name: Push App Image to DigitalOcean Container Registry\n        uses: docker/build-push-action@v3\n        with:\n          context: ${{ env.PROJECT_DIR }}\n          push: true\n          tags: \"${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}\"\n\n  snyk-iac-security-check:\n    runs-on: ubuntu-latest\n    needs: build-and-push-app-image\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install Snyk\n        uses: snyk/actions/setup@master\n\n      - name: Check for Kubernetes manifests vulnerabilities\n        run: |\n          snyk iac test \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --target-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=${{ env.ENVIRONMENT }} \\\n            --sarif-file-output=snyk-iac-scan.sarif \\\n            --report\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: ${{ env.PROJECT_DIR }}\n    \n      - name: Upload Snyk IAC SARIF file\n        if: ${{ always() }}\n        uses: github/codeql-action/upload-sarif@v2\n        with:\n          sarif_file: ${{ env.PROJECT_DIR }}/snyk-iac-scan.sarif\n          category: snyk-iac-scan\n          \n      - name: Notify using Slack about Snyk Scan Issues\n        if: ${{ always() }}\n        uses: 8398a7/action-slack@v3\n        with:\n          status: custom\n          fields: workflow,job,commit,repo,ref,author,took\n          custom_payload: |\n            {\n              attachments: [\n              {\n                color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',\n                text:`\n                  ${process.env.AS_WORKFLOW}\\n\n                  *Environment*: ${process.env.ENVIRONMENT}\\n\n                  *Job:* ${process.env.AS_JOB}\\n\n                  *Commit:* (${process.env.AS_COMMIT})\\n\n                  *Repo:* ${process.env.AS_REPO}\\n\n                  *Ref:* ${process.env.AS_REF}\\n\n                  *Author:* ${process.env.AS_AUTHOR}\\n\n                  *Status:* ${{ job.status }} in ${process.env.AS_TOOK}\\n\n                  *Snyk scan results:* https://app.snyk.io\n                `,\n              }]\n            }\n        env:\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n\n  deploy-to-k8s:\n    runs-on: ubuntu-latest\n    needs:\n      - snyk-iac-security-check\n      - build-and-push-app-image\n\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Install kubectl\n        uses: azure/setup-kubectl@v3\n\n      - name: Configure kubectl\n        run: |\n          doctl kubernetes cluster kubeconfig save ${{ secrets.DOKS_CLUSTER }} --expiry-seconds 600\n\n      - name: Configure app deployment registry\n        run: |\n          IMAGE_TAG=\"${{ github.sha }}\"\n          DOCKER_IMAGE=\"${{ secrets.DOCKER_REGISTRY }}/${PROJECT_NAME}:${IMAGE_TAG}\"\n          sed -i \"s#image:.*#image: ${DOCKER_IMAGE}#g\" deployment.yaml\n        working-directory: ${{ env.PROJECT_DIR }}/kustomize/resources/\n\n      - name: Deploy app to Kubernetes\n        run: kubectl apply --prune --all -k kustomize/\n        working-directory: ${{ env.PROJECT_DIR }}\n"
  },
  {
    "path": ".github/workflows/online-boutique-main-ci.yaml",
    "content": "name: Online Boutique CI Main\n\non:\n  # Used for testing only (can be disabled afterwards)\n  workflow_dispatch:\n  # Uncomment below lines to enable this workflow on push to main events\n  # push:\n  #   branches:\n  #     - main\n  #   paths-ignore:\n  #     - \"**/README.md\"\n  #     - \"kustomize/**\"\n  #     - \"argocd/**\"\n  #     - \".github/workflows/*\"\n\n# Do not allow concurrent workflows\n# Changes should be delivered one a time as code is merged into the main branch\nconcurrency: main-ci-dev\n\n# Global environment variables\nenv:\n  CI_COMMIT_AUTHOR: \"GitHub CI Actions\"\n  CI_COMMIT_AUTHOR_EMAIL: \"gh-ci-actions@noreply.github.com\"\n  DOCR_ENDPOINT: \"registry.digitalocean.com/microservices-demo\"\n  PROJECT_NAME: \"online-boutique\"\n\njobs:\n  # There's no point to run unit tests again after PR merge\n  # Unit testing deals with changes for the affected components,\n  #   and that it is already taken care in the PR workflow\n\n  # What it makes sense, is to run integration tests,\n  #   to see if the whole application is impacted after merging the changes\n  #\n  # Run deployment tests (integration tests)\n  # Please bear in mind that more tests means increased workflow run time\n  # With workflow concurrency disabled, means more waiting time for other PRs in the queue\n  deployment-tests:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Run integration tests\n        run: |\n          echo \"[INFO] Not implemented yet!\"\n\n  # Build and push project images in parallel using a matrix strategy\n  # Cuts down build time\n  build-and-push-images:\n    needs: deployment-tests\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        project:\n          - cartservice\n          - checkoutservice\n          - currencyservice\n          - emailservice\n          - frontend\n          - paymentservice\n          - productcatalogservice\n          - recommendationservice\n          - shippingservice\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Log in to DOCR with short-lived credentials\n        run: doctl registry login --expiry-seconds 600\n\n      - name: Build and push image\n        uses: docker/build-push-action@v3\n        with:\n          # cartservice is an exception - Dockerfile is placed in src/cartservice/src subfolder\n          context: \"src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}\"\n          push: true\n          tags: \"${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.sha }}\"\n\n  # Kustomize image field for each microservice present in the `src/` dir\n  # Finally, commit changes to main branch and let ArgoCD take over afterwards\n  apply-kustomize-changes:\n    needs: build-and-push-images\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Set up K8S tools\n        uses: yokawasa/action-setup-kube-tools@v0.8.2\n        with:\n          kustomize: \"4.5.7\"\n\n      - name: Kustomize dev environment images\n        run: |\n          for microservice in src/*/; do\n            microservice=\"$(basename $microservice)\"\n            if [[ \"$microservice\" == \"loadgenerator\" ]]; then\n              continue\n            fi\n            (\n              cd kustomize/dev\n              kustomize edit set image $microservice=${{ env.DOCR_ENDPOINT }}/${microservice}:${{ github.sha }}\n            )\n          done\n\n      - name: Commit Kustomize manifests for dev env\n        run: |\n          git config --global user.name \"${{ env.CI_COMMIT_AUTHOR }}\"\n          git config --global user.email \"${{ env.CI_COMMIT_AUTHOR_EMAIL }}\"\n          git add kustomize/dev/\n          git commit -m \"[CI] Bump docker images tag to ${{ github.sha }}\"\n\n      - name: Push changes\n        uses: ad-m/github-push-action@master\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/online-boutique-pr-ci.yaml",
    "content": "name: Online Boutique PR CI\n\non:\n  # Used for testing only (can be disabled afterwards)\n  workflow_dispatch:\n  # Uncomment below lines to enable this workflow on main branch PR events\n  # pull_request:\n  #   branches:\n  #     - main\n  #   paths-ignore:\n  #     - \"**/README.md\"\n  #     - \"kustomize/**\"\n  #     - \"argocd/**\"\n  #     - \".github/workflows/*\"\n\n# Do not allow concurrent workflows for PRs\n# If disabled, leads to memory exhaustion on the DOKS dev cluster\nconcurrency: pr-ci-dev\n\n# Global environment variables\nenv:\n  DOCR_ENDPOINT: \"registry.digitalocean.com/microservices-demo\"\n  CLUSTER_NAME: \"microservices-demo-dev\"\n  REGION: \"nyc1\"\n  K8S_NAMESPACE: \"microservices-demo-${{ github.event.pull_request.number }}\"\n  PROJECT_NAME: \"online-boutique\"\n\njobs:\n  # Run unit tests in parallel using below matrix to cut down time\n  # Unit tests are standalone and should not raise conflicts\n  # Each microservice is written in a specific language, hence it's added to the matrix\n  unit-tests:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        include:\n          - project_name: cartservice\n            project_language: csharp\n          - project_name: checkoutservice\n            project_language: golang\n          - project_name: currencyservice\n            project_language: javascript\n          - project_name: emailservice\n            project_language: python\n          - project_name: frontend\n            project_language: golang\n          - project_name: paymentservice\n            project_language: javascript\n          - project_name: productcatalogservice\n            project_language: golang\n          - project_name: recommendationservice\n            project_language: python\n          - project_name: shippingservice\n            project_language: golang\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n        with:\n          ref: ${{github.event.pull_request.head.ref}}\n          repository: ${{github.event.pull_request.head.repo.full_name}}\n\n      - name: Set up Go env\n        if: ${{ matrix.project_language == 'golang' }}\n        uses: actions/setup-go@v3\n        with:\n          go-version: \"1.19\"\n\n      - name: Go Unit Tests\n        if: ${{ matrix.project_language == 'golang' }}\n        timeout-minutes: 5\n        run: |\n          ( \n            cd src/${{ matrix.project_name }}\n            go test \n          )\n\n      - name: Set up C# env\n        if: ${{ matrix.project_language == 'csharp' }}\n        uses: actions/setup-dotnet@v2\n        with:\n          dotnet-version: \"6.0\"\n          include-prerelease: true\n\n      - name: C# Unit Tests\n        if: ${{ matrix.project_language == 'csharp' }}\n        timeout-minutes: 5\n        run: dotnet test src/${{ matrix.project_name }}/\n\n      - name: Set up NodeJS env\n        if: ${{ matrix.project_language == 'javascript' }}\n        uses: actions/setup-node@v3\n        with:\n          node-version: 18\n\n      - name: Javascript Unit Tests\n        if: ${{ matrix.project_language == 'javascript' }}\n        timeout-minutes: 5\n        run: |\n          ( \n            cd src/${{ matrix.project_name }}\n            npm install\n            npm run test \n          )\n\n      - name: Set up Python env\n        if: ${{ matrix.project_language == 'python' }}\n        uses: actions/setup-python@v3\n        with:\n          python-version: \"3.7\"\n\n      - name: Python Unit Tests\n        if: ${{ matrix.project_language == 'python' }}\n        timeout-minutes: 5\n        run: |\n          ( \n            cd src/${{ matrix.project_name }}\n            pip install -r requirements.txt\n            pytest\n          )\n\n  # Run deployment tests (smoke tests)\n  # You can add integration tests as well\n  # Please bear in mind that more tests means increased workflow run time\n  # With workflow concurrency disabled, means more waiting time for other PRs in the queue\n  deployment-tests:\n    needs: unit-tests\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n        with:\n          ref: ${{github.event.pull_request.head.ref}}\n          repository: ${{github.event.pull_request.head.repo.full_name}}\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Log in to DOCR with short-lived credentials\n        run: doctl registry login --expiry-seconds 1200\n\n      - name: Set up K8S tools\n        uses: yokawasa/action-setup-kube-tools@v0.8.2\n        with:\n          kubectl: \"1.25.2\"\n          kustomize: \"4.5.7\"\n          tilt: \"0.30.9\"\n\n      - name: Configure kubectl for DOKS with short-lived credentials\n        run: doctl kubernetes cluster kubeconfig save ${{ env.CLUSTER_NAME }} --expiry-seconds 1200\n\n      - name: Deploy microservices to DOKS\n        timeout-minutes: 10\n        run: |\n          # Bring all microservices up using Tilt and wait for all deployments\n          cp tilt-resources/dev/tilt_config.json .\n          tilt ci -- \\\n            --allowed_contexts \"do-${{ env.REGION }}-${{ env.CLUSTER_NAME }}\" \\\n            --default_registry \"${{ env.DOCR_ENDPOINT }}\" \\\n            --environment \"dev\" \\\n            --namespace \"${{ env.K8S_NAMESPACE }}\"\n\n      - name: Build loadgenerator image\n        uses: docker/build-push-action@v3\n        with:\n          context: \"src/loadgenerator\"\n          push: true\n          tags: \"${{ env.DOCR_ENDPOINT }}/loadgenerator\"\n\n      - name: Smoke tests\n        timeout-minutes: 10\n        run: |\n          # Prepare load generator\n          # Inject workflow custom docker image\n          sed -i \"s#<LOAD_GENERATOR_IMAGE>#${{ env.DOCR_ENDPOINT }}/loadgenerator#g\" loadgenerator.yaml\n\n          # Deploy load generator\n          kubectl apply -f loadgenerator.yaml -n ${{ env.K8S_NAMESPACE }}\n\n          # Wait for load generator deployment to be ready\n          kubectl wait --for=condition=available --timeout=60s deployment/loadgenerator -n ${{ env.K8S_NAMESPACE }} || {\n            # Show why load generator failed to start\n            echo \"[INFO] Load generator pod events\"\n            kubectl describe pod -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -10\n            exit 1\n          }\n\n          # Run smoke tests\n          REQUEST_COUNT=\"0\"\n          while [[ \"$REQUEST_COUNT\"  -lt \"50\"  ]]; do\n            sleep 5\n            REQUEST_COUNT=$(kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | grep Aggregated | awk '{print $2}')\n          done\n          # ensure there are no errors hitting endpoints\n          ERROR_COUNT=$(kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | grep Aggregated | awk '{print $3}' | sed \"s/[(][^)]*[)]//g\")\n          if [[ \"$ERROR_COUNT\" -gt \"0\" ]]; then\n            # Print final results\n            echo \"[INFO] Load generator results\"\n            kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -20\n            exit 1\n          fi\n\n          # Print final results\n          echo \"[INFO] Load generator results\"\n          kubectl logs -l app=loadgenerator -n ${{ env.K8S_NAMESPACE }} | tail -20\n        working-directory: \"src/loadgenerator\"\n\n      - name: Clean up Tilt microservices environment\n        if: ${{ always() }}\n        run: |\n          # Remove all microservices and the namespace created by Tilt\n          tilt down --delete-namespaces -- --namespace \"${{ env.K8S_NAMESPACE }}\"\n\n      - name: Clean up Tilt docker images from registry\n        if: ${{ always() }}\n        run: |\n          # Remove Tilt docker images from registry\n          for tilt_repo in $(docker images --format \"{{.Repository}}:{{.Tag}}\" | grep \"tilt-.*[a-z|0-9]\"); do\n            repo_and_tag=\"${tilt_repo##*/}\"\n            repo=\"${repo_and_tag%%:*}\"\n            tag=\"${repo_and_tag##*:}\"\n            echo \"[INFO] Deleting tag $tag from repo $repo ...\"\n            doctl registry repository delete-tag \"$repo\" \"$tag\" -f\n          done\n          echo \"[INFO] Remember to run the DOCR garbage collector from time to time!\"\n"
  },
  {
    "path": ".github/workflows/online-boutique-pr-kustomize-validation.yaml",
    "content": "name: Online Boutique PR Kustomize Validation\n\non:\n  workflow_dispatch:\n  # pull_request:\n  #   branches:\n  #     - main\n  #   paths:\n  #     - \"kustomize/**\"\n\nenv:\n  KUBECONFORM_VERSION: \"0.5.0\"\n  KUBERNETES_VERSION: \"1.24.4\"\n\njobs:\n  job:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Set up kubeconform\n        run: |\n          (\n            cd /tmp\n            wget \"https://github.com/yannh/kubeconform/releases/download/v${{ env.KUBECONFORM_VERSION }}/kubeconform-linux-amd64.tar.gz\"\n            tar xvf kubeconform-linux-amd64.tar.gz\n            chmod u+x ./kubeconform\n          )\n\n      - name: Kustomize linting using kubeconform\n        run: |\n          # Test each overlay using kubeconform\n          for kustomize_overlay in kustomize/*/; do\n            kustomize build \"$kustomize_overlay\" | \\\n              /tmp/kubeconform -kubernetes-version \"${{env.KUBERNETES_VERSION}}\" -summary -verbose\n          done\n"
  },
  {
    "path": ".github/workflows/online-boutique-release.yaml",
    "content": "name: Online Boutique Release\n\non:\n  workflow_dispatch:\n  # push:\n  #   # Trigger on push events to any tag matching semantic versioning\n  #   tags:\n  #     - 'v[0-9]+\\.[0-9]+\\.[0-9]+'\n\nenv:\n  RELEASE_COMMIT_AUTHOR: \"GitHub Release Actions\"\n  RELEASE_COMMIT_AUTHOR_EMAIL: \"gh-release-actions@noreply.github.com\"\n  DOCR_ENDPOINT: \"registry.digitalocean.com/microservices-demo\"\n  PROJECT_NAME: \"online-boutique\"\n\njobs:\n  validation-tests:\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"[INFO] Not implemented yet!\"\n\n  build-and-push-release-images:\n    needs: validation-tests\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        project:\n          - cartservice\n          - checkoutservice\n          - currencyservice\n          - emailservice\n          - frontend\n          - paymentservice\n          - productcatalogservice\n          - recommendationservice\n          - shippingservice\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Install doctl\n        uses: digitalocean/action-doctl@v2\n        with:\n          token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}\n\n      - name: Log in to DOCR with short-lived credentials\n        run: doctl registry login --expiry-seconds 600\n\n      - name: Build and push image\n        uses: docker/build-push-action@v3\n        with:\n          # cartservice is an exception - Dockerfile is placed in src/cartservice/src subfolder\n          context: \"src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}\"\n          push: true\n          tags: \"${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.ref_name }}\"\n\n  # Kustomize image field for each microservice present in the `src/` dir\n  # Finally, commit changes to main branch and let ArgoCD take over afterwards\n  apply-kustomize-changes:\n    needs: build-and-push-release-images\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n\n      - name: Set up K8S tools\n        uses: yokawasa/action-setup-kube-tools@v0.8.2\n        with:\n          kustomize: \"4.5.7\"\n\n      - name: Kustomize staging environment images\n        run: |\n          for microservice in src/*/; do\n            microservice=\"$(basename $microservice)\"\n            if [[ \"$microservice\" == \"loadgenerator\" ]]; then\n              continue\n            fi\n            (\n              cd kustomize/staging/\n              kustomize edit set image $microservice=${{ env.DOCR_ENDPOINT }}/${microservice}:${{ github.ref_name }}\n            )\n          done\n\n      - name: Commit Kustomize manifests for staging env\n        run: |\n          git config --global user.name \"${{ env.RELEASE_COMMIT_AUTHOR }}\"\n          git config --global user.email \"${{ env.RELEASE_COMMIT_AUTHOR_EMAIL }}\"\n          git add kustomize/staging/\n          git commit -m \"[Release] Bump docker images tag to ${{ github.ref_name }}\"\n\n      - name: Push changes\n        uses: ad-m/github-push-action@master\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n\n"
  },
  {
    "path": ".github/workflows/online-boutique-snyk-docker-scan.yaml",
    "content": "name: Online Boutique Snyk Docker Scan\n\non:\n  # pull_request:\n  #   branches:\n  #     - main\n  #   paths:\n  #     - \"src/**/Dockerfile\"\n\n  # Below configuration is used for manual workflow dispatch\n  workflow_dispatch:\n    inputs:\n      snyk_fail_threshold:\n        description: |\n          Sets fail threshold for Snyk \n          (low | medium | high | critical)\n        required: true\n        default: \"high\"\n\nenv:\n  DOCR_ENDPOINT: \"registry.digitalocean.com/microservices-demo\"\n  PROJECT_NAME: \"online-boutique\"\n  SNYK_FAIL_THRESHOLD: \"high\"\n\njobs:\n  container-security-check:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        project:\n          - cartservice\n          - checkoutservice\n          - currencyservice\n          - emailservice\n          - frontend\n          - paymentservice\n          - productcatalogservice\n          - recommendationservice\n          - shippingservice\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n        with:\n          ref: ${{ github.event.pull_request.head.ref }}\n          repository: ${{ github.event.pull_request.head.repo.full_name }}\n\n      - name: Install Snyk\n        uses: snyk/actions/setup@master\n\n      - name: Build app image for Snyk container scanning\n        uses: docker/build-push-action@v3\n        with:\n          # Cartservice is an exception - Dockerfile is placed in `src/cartservice/src` subfolder\n          context: \"src/${{ matrix.project }}/${{ matrix.project == 'cartservice' && 'src' || ''}}\"\n          push: false\n          tags: \"${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.event.pull_request.head.sha }}\"\n\n      - name: Check application container vulnerabilities\n        run: |\n          # Cartservice is an exception regarding project layout\n          # It uses a nested src subfolder - `src/cartservice/src`\n          if [[ \"${{ matrix.project }}\" == \"cartservice\" ]]; then\n            cd src/\n          fi\n          snyk container test \"${{ env.DOCR_ENDPOINT }}/${{ matrix.project }}:${{ github.event.pull_request.head.sha }}\" \\\n            --file=Dockerfile \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --target-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=${{ matrix.project }}\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: \"src/${{ matrix.project }}\"\n"
  },
  {
    "path": ".github/workflows/online-boutique-snyk-iac-scan.yaml",
    "content": "name: Online Boutique Snyk IAC Scan\n\non:\n  # pull_request:\n  #   branches:\n  #     - main\n  #   paths:\n  #     - \"argocd/**\"\n  #     - \"kustomize/**\"\n\n  # Below configuration is used for manual workflow dispatch\n  workflow_dispatch:\n    inputs:\n      snyk_fail_threshold:\n        description: |\n          Sets fail threshold for Snyk \n          (low | medium | high | critical)\n        required: true\n        default: \"high\"\n\nenv:\n  PROJECT_NAME: \"online-boutique\"\n  SNYK_FAIL_THRESHOLD: \"high\"\n\njobs:\n  iac-security-check:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n        with:\n          ref: ${{ github.event.pull_request.head.ref }}\n          repository: ${{ github.event.pull_request.head.repo.full_name }}\n\n      - name: Install Snyk\n        uses: snyk/actions/setup@master\n\n      - name: Check for Kubernetes manifests vulnerabilities\n        run: |\n          snyk iac test \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --target-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=\"kustomize-PR#${{ github.event.pull_request.number }}\" \\\n            --report\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: kustomize\n\n      - name: Check for Argo CD manifests vulnerabilities\n        run: |\n          snyk iac test \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --target-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=\"argocd-PR#${{ github.event.pull_request.number }}\" \\\n            --report\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: argocd\n"
  },
  {
    "path": ".github/workflows/online-boutique-snyk-source-code-scan.yaml",
    "content": "name: Online Boutique Snyk Source Code Scan\n\non:\n  # pull_request:\n  #   branches:\n  #     - main\n  #   paths:\n  #     - \"src/**\"\n\n  # Below configuration is used for manual workflow dispatch\n  workflow_dispatch:\n    inputs:\n      snyk_fail_threshold:\n        description: |\n          Sets fail threshold for Snyk \n          (low | medium | high | critical)\n        required: true\n        default: \"high\"\n\nenv:\n  PROJECT_NAME: \"online-boutique\"\n  SNYK_FAIL_THRESHOLD: \"high\"\n\njobs:\n  source-code-security-check:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - project_name: cartservice\n            project_language: dotnet\n          - project_name: checkoutservice\n            project_language: golang\n          - project_name: currencyservice\n            project_language: node\n          - project_name: emailservice\n            project_language: python\n          - project_name: frontend\n            project_language: golang\n          - project_name: paymentservice\n            project_language: node\n          - project_name: productcatalogservice\n            project_language: golang\n          - project_name: recommendationservice\n            project_language: python\n          - project_name: shippingservice\n            project_language: golang\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n        with:\n          ref: ${{ github.event.pull_request.head.ref }}\n          repository: ${{ github.event.pull_request.head.repo.full_name }}\n\n      - name: Install Snyk\n        uses: snyk/actions/setup@master\n\n      - name: Setup dotnet\n        if: ${{ matrix.project_language == 'dotnet' }}\n        uses: actions/setup-dotnet@v3\n        with:\n          dotnet-version: '6.0'\n\n      - name: Restore dotnet project dependencies\n        if: ${{ matrix.project_language == 'dotnet' }}\n        run: dotnet restore\n        working-directory: \"src/${{ matrix.project_name }}\"\n      \n      - name: Set up Python env\n        if: ${{ matrix.project_language == 'python' }}\n        uses: actions/setup-python@v3\n        with:\n          python-version: \"3.7\"\n      \n      - name: Install Python project dependencies\n        if: ${{ matrix.project_language == 'python' }}\n        run: pip install -r requirements.txt\n        working-directory: \"src/${{ matrix.project_name }}\"\n\n      - name: Check application source code for vulnerabilities\n        run: |\n          # Cartservice is an exception regarding project layout\n          # It uses a nested src subfolder - `src/cartservice/src`\n          if [[ \"${{ matrix.project_name }}\" == \"cartservice\" ]]; then\n            cd src/\n          fi\n          snyk code test \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }}\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: \"src/${{ matrix.project_name }}\"\n      \n      - name: Check 3rd party source code for vulnerabilities\n        run: |\n          # Cartservice is an exception regarding project layout \n          # It uses a nested src subfolder - `src/cartservice/src`\n          if [[ \"${{ matrix.project_name }}\" == \"cartservice\" ]]; then\n            cd src/\n          fi\n          snyk test \\\n            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \\\n            --project-name=${{ env.PROJECT_NAME }} \\\n            --target-reference=${{ matrix.project_name }}\n        env:\n          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}\n        working-directory: \"src/${{ matrix.project_name }}\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# macOS\n.DS_Store\n"
  },
  {
    "path": "README.md",
    "content": "# DigitalOcean Kubernetes Sample Apps\n\nThis repository contains a collection of Kubernetes applications that can be used in various projects. Each sample application has a dedicated folder to keep all resources, and main documentation.\n\nKubernetes sample applications provided by this repository:\n\n- [bookinfo-example](bookinfo-example/) - Deploy the [Bookinfo](https://istio.io/latest/docs/examples/bookinfo) sample application.\n- [doks-example](doks-example/) - Deploy your first application (workload) to a fresh DOKS cluster.\n- [emojivoto-example](emojivoto-example/) - Deploy the [Emojivoto](https://github.com/BuoyantIO/emojivoto) sample application.\n- [game-2048-example](game-2048-example/) - Build and deploy the [2048 game](https://en.wikipedia.org/wiki/2048_(video_game)) application.\n- [podinfo-example](podinfo-example/) - Deploy the [Podinfo](https://github.com/stefanprodan/podinfo) sample application.\n"
  },
  {
    "path": "bookinfo-example/README.md",
    "content": "# Overview\n\nThe [Bookinfo](https://istio.io/latest/docs/examples/bookinfo) application displays information about a book, similar to a single catalog entry of an online book store. Displayed on the page is a description of the book, book details (ISBN, number of pages, and so on), and a few book reviews.\n\nThe `Bookinfo` application is broken into four separate microservices:\n\n- `productpage` - calls the details and reviews microservices to populate the page.\n- `details` - contains book information.\n- `reviews` - contains book reviews. It also calls the ratings microservice.\n- `ratings` - contains book ranking information that accompanies a book review.\n\nPlease visit the [Bookinfo application](https://istio.io/latest/docs/examples/bookinfo) documentation page for more details.\n\n## Requirements\n\nTo complete all steps and deploy the `Bookinfo` sample application, you will need:\n\n1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running.\n2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction.\n3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository.\n\n## Deploying to Kubernetes\n\nThe [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Bookinfo` application Kubernetes resources.\n\nFirst, you need to clone this repository:\n\n```shell\ngit clone https://github.com/digitalocean/kubernetes-sample-apps.git\n```\n\nThen, change directory to your local copy:\n\n```shell\ncd kubernetes-sample-apps\n```\n\nNow, create Bookinfo sample application Kubernetes resources using the kubectl kustomize option (`-k` flag):\n\n```shell\nkubectl apply -k bookinfo-example/kustomize\n```\n\nThe output looks similar to:\n\n```text\nnamespace/bookinfo created\nserviceaccount/bookinfo-details created\nserviceaccount/bookinfo-productpage created\nserviceaccount/bookinfo-ratings created\nserviceaccount/bookinfo-reviews created\nservice/details created\nservice/productpage created\nservice/ratings created\nservice/reviews created\ndeployment.apps/details-v1 created\ndeployment.apps/productpage-v1 created\ndeployment.apps/ratings-v1 created\ndeployment.apps/reviews-v1 created\ndeployment.apps/reviews-v2 created\ndeployment.apps/reviews-v3 created\n```\n\nIf everything went well, you should have a new Kubernetes namespace created named `bookinfo`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Bookinfo application pods should be up and running):\n\n```shell\nkubectl get all -n bookinfo\n```\n\nThe output looks similar to:\n\n```text\nNAME                                  READY   STATUS    RESTARTS   AGE\npod/details-v1-7694bf8b6f-zgdts       1/1     Running   0          82m\npod/productpage-v1-659d8f84c9-cr446   1/1     Running   0          82m\npod/ratings-v1-65785878bf-7kr2h       1/1     Running   0          82m\npod/reviews-v1-b98448d4f-zrfbd        1/1     Running   0          82m\npod/reviews-v2-867f95557c-shsw9       1/1     Running   0          81m\npod/reviews-v3-7c769464df-gbv5x       1/1     Running   0          81m\n\nNAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE\nservice/details       ClusterIP   10.245.223.202   <none>        9080/TCP   82m\nservice/productpage   ClusterIP   10.245.139.105   <none>        9080/TCP   82m\nservice/ratings       ClusterIP   10.245.229.118   <none>        9080/TCP   82m\nservice/reviews       ClusterIP   10.245.227.244   <none>        9080/TCP   82m\n\nNAME                             READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/details-v1       1/1     1            1           82m\ndeployment.apps/productpage-v1   1/1     1            1           82m\ndeployment.apps/ratings-v1       1/1     1            1           82m\ndeployment.apps/reviews-v1       1/1     1            1           82m\ndeployment.apps/reviews-v2       1/1     1            1           82m\ndeployment.apps/reviews-v3       1/1     1            1           82m\n\nNAME                                        DESIRED   CURRENT   READY   AGE\nreplicaset.apps/details-v1-7694bf8b6f       1         1         1       82m\nreplicaset.apps/productpage-v1-659d8f84c9   1         1         1       82m\nreplicaset.apps/ratings-v1-65785878bf       1         1         1       82m\nreplicaset.apps/reviews-v1-b98448d4f        1         1         1       82m\nreplicaset.apps/reviews-v2-867f95557c       1         1         1       82m\nreplicaset.apps/reviews-v3-7c769464df       1         1         1       82m\n```\n\nFinally, port-forward the `productpage` service using `kubectl`:\n\n```shell\nkubectl port-forward service/productpage -n bookinfo 9080:9080\n```\n\nOpen a web browser and point to [localhost:9080](http://localhost:9080/). You should see the `productpage` service welcome page:\n\n![Product Page Welcome](assets/images/product-page-welcome.png)\n\n## Cleaning Up\n\nTo clean up all Kubernetes resources created by the Bookinfo sample application, below command must be used:\n\n```shell\nkubectl delete ns bookinfo\n```\n\n**Note:**\n\nKubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k bookinfo-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail.\n"
  },
  {
    "path": "bookinfo-example/kustomize/kustomization.yaml",
    "content": "## Bookinfo Sample Application Kustomization\n\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Making sure all resources used in this tutorial are created in a dedicated namespace\n# Also specific annotations are added for later identification\nnamespace: bookinfo\ncommonAnnotations:\n  provider: kubernetes-sample-apps\n\n# Bookinfo resources (namespace, services, deployments, etc)\nresources:\n  - resources/namespace.yaml\n  - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/platform/kube/bookinfo.yaml\n  # If you want to apply Istio configuration on top of the bookinfo deployment, uncomment below lines (assuming you have Istio already installed)\n  # - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/networking/bookinfo-gateway.yaml\n  # - https://raw.githubusercontent.com/istio/istio/release-1.14/samples/bookinfo/networking/destination-rule-all.yaml\n"
  },
  {
    "path": "bookinfo-example/kustomize/resources/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: bookinfo\n"
  },
  {
    "path": "doks-example/.travis.yml",
    "content": "services:\n  - 'docker'\n\nscript:\n  - docker build -t doks-example .\n  - docker run --rm -it doks-example sleep 1\n\nnotifications:\n  email: false"
  },
  {
    "path": "doks-example/Dockerfile",
    "content": "FROM nginx\n\nADD web /usr/share/nginx/html"
  },
  {
    "path": "doks-example/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 DigitalOcean\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "doks-example/README.md",
    "content": "[![Build Status](https://travis-ci.org/digitalocean/doks-example.svg?branch=master)](https://travis-ci.org/digitalocean/doks-example)\n\n# Getting Started\n\n 1. Create your Kubernetes cluster: `doctl k8s cluster create example`\n 1. Check that your cluster is available: `kubectl --context do-nyc1-example get nodes`\n 1. Deploy a workload to your cluster: `kubectl --context do-nyc1-example apply -f manifest.yaml`\n 1. Wait for the service to be ready: `script/wait-for-service do-nyc1-example doks-example`\n 1. Open the returned IP address in your browser, or run `open http://$(kubectl --context do-nyc1-example get service doks-example --template=\"{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}\")`\n\nOr you can just run `script/up` to do all of this.\n\n## Cleaning up\n\nRun `script/down` to tear down the cluster and remove the load-balancer.\n\n**Note:** If you delete the cluster directly, the load-balancer will stick around and result in charges.\n"
  },
  {
    "path": "doks-example/manifest.yaml",
    "content": "---\nkind: Service\napiVersion: v1\nmetadata:\n  name: doks-example\nspec:\n  type: LoadBalancer\n  selector:\n    app: doks-example\n  ports:\n    - name: http\n      protocol: TCP\n      port: 80\n      targetPort: 80\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: doks-example\nspec:\n  replicas: 2\n  selector:\n    matchLabels:\n      app: doks-example\n  template:\n    metadata:\n      labels:\n        app: doks-example\n    spec:\n      containers:\n      - name: nginx\n        image: digitalocean/doks-example\n        ports:\n        - containerPort: 80\n          protocol: TCP\n"
  },
  {
    "path": "doks-example/script/docker-publish",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\nTARGET=\"digitalocean/doks-example\"\ndocker build -t ${TARGET} .\ndocker push ${TARGET}\n"
  },
  {
    "path": "doks-example/script/down",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\nCLUSTER=\"example\"\ndoctl compute load-balancer delete --force $(kubectl get svc doks-example -o jsonpath=\"{.metadata.annotations.kubernetes\\.digitalocean\\.com/load-balancer-id}\")\ndoctl k8s cluster delete ${CLUSTER}"
  },
  {
    "path": "doks-example/script/up",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\nCLUSTER=\"example\"\nSERVICE=\"doks-example\"\nCONTEXT=\"do-nyc1-${CLUSTER}\"\ndoctl k8s cluster create ${CLUSTER}\nkubectl --context ${CONTEXT} apply -f manifest.yaml\nscript/wait-for-service ${CONTEXT} ${SERVICE}\nopen http://$(kubectl --context ${CONTEXT} get service ${SERVICE} --template=\"{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}\")"
  },
  {
    "path": "doks-example/script/wait-for-service",
    "content": "#!/usr/bin/env bash\n# Pass the name of a service to check: sh wait-for-service.sh example\nset -euo pipefail\nEXTERNAL_IP=\"\"\nCONTEXT=\"$1\"\nSERVICE=\"$2\"\nwhile [ -z $EXTERNAL_IP ]; do\n  EXTERNAL_IP=$(kubectl --context ${CONTEXT} get service ${SERVICE} --template=\"{{range .status.loadBalancer.ingress}}{{.ip}}{{end}}\")\n  if [ -z \"${EXTERNAL_IP}\" ]; then\n    echo \"Waiting for external IP...\"\n    sleep 10\n  fi\ndone\necho \"Ready: ${EXTERNAL_IP}\"\n"
  },
  {
    "path": "doks-example/web/index.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <link rel=\"stylesheet\" href=\"https://assets.digitalocean.com/bui/1.2.2/bui.css\">\n        <link href=\"./style.css\" type=\"text/css\" rel=\"stylesheet\">\n\n        <meta name=\"viewport\" content=\"width=device-width, maximum-scale=1.0\">\n\n        <title>Welcome to DOKS</title>\n    </head>\n    <body>\n        <div class=\"Header bui-Inline\">\n            <svg class=\"Icon bui-Icon--xlarge\"><use xlink:href=\"#logo\"></use></svg>\n        </div>\n\n        <main>\n            <div class=\"bui-GridContainer bui-u-flexMiddle\">\n                <div class=\"bui-Col-6\">\n                    <div id=\"welcome\">\n                        <h1 class=\"bui-u-textBold\">Welcome to DOKS</h1>\n                        <p>Congratulations, you deployed your first workload! You have just created a <span class=\"bui-u-textCode\">Deployment</span> responsible for managing 2 instances of Pod workloads running the docker image given in the manifest. In addition to this <span class=\"bui-u-textCode\">Deployment</span>, you have also configured a <span class=\"bui-u-textCode\">Service</span> of type <span class=\"bui-u-textCode\">LoadBalancer</span> that exposes the <span class=\"bui-u-textCode\">Deployment</span> publicly using a DigitalOcean Load Balancer, which is a paid service.</p>\n                    </div>\n                </div>\n\n                <div class=\"bui-Col-6\">\n                    <div id=\"running\">\n                        <h2>Here's what's running:</h2>\n                        <pre><code id=\"manifest\" class=\"bui-CodeBlock\">---\nkind: Service\napiVersion: v1\nmetadata:\n  name: doks-example\nspec:\n  type: LoadBalancer\n  selector:\n    app: doks-example\n  ports:\n    - name: http\n      protocol: TCP\n      port: 80\n      targetPort: 80\n---\napiVersion: extensions/v1beta1\nkind: Deployment\nmetadata:\n  name: doks-example\nspec:\n  replicas: 2\n  template:\n    metadata:\n      labels:\n        app: doks-example\n    spec:\n      containers:\n      - name: nginx\n        image: digitalocean/doks-example\n        ports:\n        - containerPort: 80\n          protocol: TCP\n                        </code></pre>\n                    </div>\n                </div>\n            </div>\n\n            <div class=\"bui-Col\">\n                <div id=\"more\">\n                    <h3>Learn more about DigitalOcean Kubernetes Service</h3>\n                    <ul class=\"bui-BlockGrid bui-BlockGrid-4 bui-u-flexDeepMatch\">\n                        <li>\n                            <div class=\"more-item\">\n                                <span class=\"more-type\">White Paper</span>\n                                <h3 class=\"bui-u-textPrimary bui-u-textRegular\">\n                                    <a href=\"https://www.digitalocean.com/community/tutorials/white-paper-running-cloud-native-applications-on-digitalocean-kubernetes\">Running Cloud Native Applications</a>\n                                </h3>\n                                <p>Running Cloud Native Application on DigitalOcean Kubernetes Service.</p>\n                            </div>\n                        </li>\n                        <li>\n                            <div class=\"more-item\">\n                                <span class=\"more-type\">Product Docs</span>\n                                <h3 class=\"bui-u-textPrimary bui-u-textRegular\">\n                                    <a href=\"https://www.digitalocean.com/docs/kubernetes/quickstart/\">\n                                        Quick Start\n                                    </a>\n                                </h3>\n                                <p>From zero to working in a few minutes.</p>\n                            </div>\n                        </li>\n                        <li>\n                            <div class=\"more-item\">\n                                <span class=\"more-type\">Tutorial</span>\n                                <h3 class=\"bui-u-textPrimary bui-u-textRegular\">\n                                    <a href=\"https://www.digitalocean.com/community/tutorials/architecting-applications-for-kubernetes\">\n                                        Architecting Applications for Kubernetes\n                                    </a>\n                                </h3>\n                                <p>Design your application for Kubernetes.</p>\n                            </div>\n                        </li>\n                        <li>\n                            <div class=\"more-item\">\n                                <span class=\"more-type\">Education</span>\n                                <h3 class=\"bui-u-textPrimary bui-u-textRegular\">\n                                    <a href=\"https://www.digitalocean.com/resources/kubernetes\">\n                                        Resource Center\n                                    </a>\n                                </h3>\n                                <p>Learn more about building and deploying microservices with a robust library of Kubernetes assets.</p>\n                            </div>\n                        </li>\n                    </ul>\n                </div>\n            </div>\n        </main>\n\n        <div id=\"footer\" class=\"bui-Footer\">\n            <a href=\"https://blog.digitalocean.com/\">Blog</a>\n            <a href=\"https://www.digitalocean.com/pricing\">Pricing</a>\n            <a href=\"https://www.digitalocean.com/company/careers\">Careers</a>\n            <a href=\"https://www.digitalocean.com/legal/terms\">Terms</a>\n            <a href=\"https://www.digitalocean.com/legal/privacy\">Privacy</a>\n            <a href=\"https://status.digitalocean.com\">Status</a>\n            <a href=\"https://developers.digitalocean.com\">API Docs</a>\n            <a href=\"https://www.digitalocean.com/community\">Tutorials</a>\n            <a href=\"https://cloudsupport.digitalocean.com/\">Support</a>\n        </div>\n\n        <script src=\"https://code.jquery.com/jquery-3.2.1.slim.min.js\"></script>\n        <script src=\"https://assets.digitalocean.com/bui/1.2.2/bui.js\"></script>\n\n        <script>\n            var xhr = new XMLHttpRequest;\n            xhr.open('get','https://assets.digitalocean.com/bui/1.2.2/bui-icons.svg',true);\n            xhr.onreadystatechange = function(){\n              if (xhr.readyState != 4) return;\n              var svg = xhr.responseXML.documentElement;\n              svg = document.importNode(svg,true); // surprisingly optional in these browsers\n              document.head.appendChild(svg);\n            };\n            xhr.send();\n        </script>\n\n    </body>\n</html>\n"
  },
  {
    "path": "doks-example/web/style.css",
    "content": "html {\n    height: 100%;\n}\n\nbody {\n    margin: 0;\n    padding: 25px;\n    height: 100%;\n\n    background-color: #0a1e99;\n    background-image: url(\"/bg.png\");\n    background-repeat: no-repeat;\n    background-position: right bottom;\n    background-size: 800px;\n}\n\nmain {\n    margin: auto;\n    width: 900px;\n}\n\nh1, h2, h3 {\n    color: white;\n}\n\npre {\n    border: 0;\n    background-color: #031b4d;\n    color: white;\n    wdith: 100%;\n    max-height: 400px;\n    overflow: scroll;\n}\n\n.Header {\n    opacity: 0.5;\n    color: white;\n    fill: white;\n}\n\n#welcome {\n    color: white;\n}\n\n#welcome span.bui-u-textCode {\n    background-color: #031b4d;\n    border: 0;\n}\n\n#running {\n    color: white;\n}\n\n#more {\n    margin-top: 30px;\n    font-size: 80%;\n}\n\n.more-item {\n    padding: 20px;\n    background-color: white;\n    border-radius: 5px;\n}\n\n.more-item h3 {\n    padding: 0;\n    margin: 10px 0 10px 0;\n}\n\n.more-type {\n    text-transform: uppercase;\n    font-size: 80%;\n}\n\n#footer {\n    background-color: transparent;\n    color: white;\n    font-size: 60%;\n}\n\n#footer a, #footer a:hover {\n    color: white;\n}\n"
  },
  {
    "path": "emojivoto-example/README.md",
    "content": "# Overview\n\n[Emojivoto](https://github.com/BuoyantIO/emojivoto) is a microservice application that allows users to vote for their favorite emoji, and tracks votes received on a leaderboard. May the best emoji win.\n\nThe application is composed of the following 3 services:\n\n* [emojivoto-web](https://github.com/BuoyantIO/emojivoto/tree/main/emojivoto-web): Web frontend and REST API.\n* [emojivoto-emoji-svc](https://github.com/BuoyantIO/emojivoto/tree/main/emojivoto-emoji-svc): gRPC API for finding and listing emoji.\n* [emojivoto-voting-svc](https://github.com/BuoyantIO/emojivoto/blob/main/emojivoto-voting-svc): gRPC API for voting and leaderboard.\n\nPlease visit the [Emojivoto](https://github.com/BuoyantIO/emojivoto) documentation page for more details.\n\n## Requirements\n\nTo complete all steps and deploy the `Emojivoto` sample application, you will need:\n\n1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running.\n2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction.\n3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository.\n\n## Deploying to Kubernetes\n\nThe [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Emojivoto` application Kubernetes resources.\n\nFirst, you need to clone this repository:\n\n```shell\ngit clone https://github.com/digitalocean/kubernetes-sample-apps.git\n```\n\nThen, change directory to your local copy:\n\n```shell\ncd kubernetes-sample-apps\n```\n\nNow, create Emojivoto sample application Kubernetes resources using the kubectl kustomize option (`-k` flag):\n\n```shell\nkubectl apply -k emojivoto-example/kustomize\n```\n\nThe output looks similar to:\n\n```text\nnamespace/emojivoto created\nserviceaccount/emoji created\nserviceaccount/voting created\nserviceaccount/web created\nservice/emoji-svc created\nservice/voting-svc created\nservice/web-svc created\ndeployment.apps/emoji created\ndeployment.apps/vote-bot created\ndeployment.apps/voting created\ndeployment.apps/web created\n```\n\nIf everything went well, you should have a new Kubernetes namespace created named `emojivoto`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Emojivoto application pods should be up and running):\n\n```shell\nkubectl get all -n emojivoto\n```\n\nThe output looks similar to:\n\n```text\nNAME                            READY   STATUS    RESTARTS   AGE\npod/emoji-84cd97f89b-cpz4l      1/1     Running   0          10m\npod/vote-bot-5b587bbff7-wqv8t   1/1     Running   0          10m\npod/voting-74ff7f8b55-5wbgt     1/1     Running   0          10m\npod/web-7dfbdc8bf5-247t9        1/1     Running   0          9m59s\n\nNAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE\nservice/emoji-svc    ClusterIP   10.245.140.136   <none>        8080/TCP,8801/TCP   10m\nservice/voting-svc   ClusterIP   10.245.217.36    <none>        8080/TCP,8801/TCP   10m\nservice/web-svc      ClusterIP   10.245.137.75    <none>        80/TCP              10m\n\nNAME                       READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/emoji      1/1     1            1           10m\ndeployment.apps/vote-bot   1/1     1            1           10m\ndeployment.apps/voting     1/1     1            1           10m\ndeployment.apps/web        1/1     1            1           10m\n\nNAME                                  DESIRED   CURRENT   READY   AGE\nreplicaset.apps/emoji-84cd97f89b      1         1         1       10m\nreplicaset.apps/vote-bot-5b587bbff7   1         1         1       10m\nreplicaset.apps/voting-74ff7f8b55     1         1         1       10m\nreplicaset.apps/web-7dfbdc8bf5        1         1         1       10m\n```\n\nFinally, port-forward the `web-svc` service using `kubectl`:\n\n```shell\nkubectl port-forward service/web-svc -n emojivoto 8080:80\n```\n\nOpen a web browser and point to [localhost:8080](http://localhost:8080/). You should see the Emojivoto application welcome page:\n\n![Emojivoto Welcome Page](assets/images/emojivoto-welcome-page.png)\n\n## Cleaning Up\n\nTo clean up all Kubernetes resources created by the Emojivoto sample application, below command must be used:\n\n```shell\nkubectl delete ns emojivoto\n```\n\n**Note:**\n\nKubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k emojivoto-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail.\n"
  },
  {
    "path": "emojivoto-example/kustomize/kustomization.yaml",
    "content": "## Emojivoto Sample Application Kustomization\n\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Making sure all resources used in this tutorial are created in a dedicated namespace\n# Also specific annotations are added for later identification\nnamespace: emojivoto\ncommonAnnotations:\n  provider: kubernetes-sample-apps\n\n# Emojivoto resources (namespace, services, deployments, etc)\nresources:\n  - github.com/BuoyantIO/emojivoto/kustomize/deployment\n\npatches:\n  - path: patches/emoji-svc.yaml\n    target:\n      version: v1\n      kind: Service\n      name: emoji-svc\n  - path: patches/voting-svc.yaml\n    target:\n      version: v1\n      kind: Service\n      name: voting-svc\n"
  },
  {
    "path": "emojivoto-example/kustomize/patches/emoji-svc.yaml",
    "content": "- op: add\n  path: /metadata/labels\n  value: \n    app: emoji-svc\n"
  },
  {
    "path": "emojivoto-example/kustomize/patches/voting-svc.yaml",
    "content": "- op: add\n  path: /metadata/labels\n  value: \n    app: voting-svc\n"
  },
  {
    "path": "game-2048-example/.dockerignore",
    "content": "**/.classpath\r\n**/.dockerignore\r\n**/.env\r\n**/.git\r\n**/.gitignore\r\n**/.project\r\n**/.settings\r\n**/.toolstarget\r\n**/.vs\r\n**/.vscode\r\n**/*.*proj.user\r\n**/*.dbmdl\r\n**/*.jfm\r\n**/charts\r\n**/docker-compose*\r\n**/compose*\r\n**/Dockerfile*\r\n**/node_modules\r\n**/npm-debug.log\r\n**/obj\r\n**/secrets.dev.yaml\r\n**/values.dev.yaml\r\nREADME.md\r\n"
  },
  {
    "path": "game-2048-example/.gitignore",
    "content": "**/node_modules\n**/dist\n"
  },
  {
    "path": "game-2048-example/Dockerfile",
    "content": "FROM node:16-slim AS builder\r\nWORKDIR /usr/src/app\r\nCOPY . .\r\nRUN npm install --include=dev\r\n#\r\n# Build mode can be set via NODE_ENV environment variable (development or production)\r\n# See project package.json and webpack.config.js\r\n#\r\nENV NODE_ENV=development\r\nRUN npm run build\r\n\r\nFROM node:16-slim\r\nRUN npm install http-server -g\r\nRUN mkdir /public\r\nWORKDIR /public\r\nCOPY --from=builder /usr/src/app/dist/ ./\r\nEXPOSE 8080\r\nUSER 1000\r\nCMD [\"http-server\"]\r\n"
  },
  {
    "path": "game-2048-example/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 DigitalOcean\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "game-2048-example/README.md",
    "content": "# Overview\n\nSample javascript application implementing the classic [2048 game](https://en.wikipedia.org/wiki/2048_(video_game)). Main project is based on the [game-2048 library](https://www.npmjs.com/package/game-2048) and [Webpack](https://webpack.js.org).\n\nMain purpose is to serve as a demo for the [DOKS-CI-CD](https://github.com/digitalocean/container-blueprints/tree/main/DOKS-CI-CD) blueprint.\n\n## Requirements\n\nTo complete all steps and deploy the `2048-game` sample application, you will need:\n\n1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running.\n2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction.\n3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository.\n4. [NodeJS](https://nodejs.org) and `npm` to build and test the 2048-game application code.\n5. [Docker Desktop](https://www.docker.com/products/docker-desktop) to build and test the 2048-game application docker image locally.\n\n## Building the 2048 Game Application\n\nMain project is `javascript` based, hence you can build the application via `npm`:\n\n```shell\nnpm install --include=dev\n\nnpm run build\n```\n\nYou can test the application locally, by running below command:\n\n```shell\nnpm start\n```\n\nAbove command will start a web server in development mode, which you can access at [localhost:8080](http://localhost:8080). Please visit the main library [configuration](https://www.npmjs.com/package/game-2048#config) section from the public npm registry to see all available options.\n\n## Building the Docker Image\n\nA sample [Dockerfile](./Dockerfile) is provided in this repository as well, to help you get started with dockerizing the 2048 game app. Depending on the `NODE_ENV` environment variable, you can create and publish a `development` or `production` ready Docker image.\n\nFirst, you need to clone this repository (if not already):\n\n```shell\ngit clone https://github.com/digitalocean/kubernetes-sample-apps.git\n```\n\nThen, change directory to your local copy:\n\n```shell\ncd kubernetes-sample-apps\n```\n\nNext, issue below command to build the docker image for the 2048 game app, Below examples assume you already have a [DigitalOcean Docker Registry](https://docs.digitalocean.com/products/container-registry) set up (make sure to replace the `<>` placeholders accordingly):\n\n```shell\ndocker build -t registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game ./game-2048-example\n```\n\n**Note:**\n\nThe sample [Dockerfile](./Dockerfile) provided in this repository is using the [multistage build](https://docs.docker.com/develop/develop-images/multistage-build) feature. It means, the final image contains only the application assets (build process artifacts are automatically discarded).\n\nThen, you can issue bellow command to launch the `2048-game` container (make sure to replace the `<>` placeholders accordingly):\n\n```shell\ndocker run --rm -it -p 8080:8080 registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game\n```\n\nNow, visit [localhost:8080](http://localhost:8080) to check the 2048 game app in your web browser. Finally, you can push the image to your DigitalOcean docker registry (make sure to replace the `<>` placeholders accordingly):\n\n```shell\ndocker push registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game\n```\n\n**Note:**\n\nPushing images to your DigitalOcean docker registry is possible only after a successful authentication. Please read the official DigitalOcean [guide](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes) and follow the steps. [Integrating with Kubernetes](https://docs.digitalocean.com/products/container-registry/how-to/use-registry-docker-kubernetes/#kubernetes-integration) step is important as well.\n\n## Deploying to Kubernetes\n\nThe [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `2048-game` Kubernetes resources.\n\nFirst, you need to clone this repository (if not already):\n\n```shell\ngit clone https://github.com/digitalocean/kubernetes-sample-apps.git\n```\n\nThen, change directory to your local copy:\n\n```shell\ncd kubernetes-sample-apps\n```\n\nNext, edit the game-2048 [deployment manifest](kustomize/resources/deployment.yaml) using your favorite text editor (preferably with YAML lint support), and replace the `<>` placeholders. For example, you can use [VS Code](https://code.visualstudio.com/):\n\n```shell\ncode game-2048-example/kustomize/resources/deployment.yaml\n```\n\nNow, create 2048 game Kubernetes resources using the kubectl kustomize option (`-k` flag):\n\n```shell\nkubectl apply -k game-2048-example/kustomize\n```\n\nThe output looks similar to:\n\n```text\nnamespace/game-2048 created\nservice/game-2048 created\ndeployment.apps/game-2048 created\n```\n\nIf everything went well, you should have a new Kubernetes namespace created named `game-2048`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all game-2048 application pods should be up and running):\n\n```shell\nkubectl get all -n game-2048\n```\n\nThe output looks similar to:\n\n```text\nNAME                            READY   STATUS    RESTARTS   AGE\npod/game-2048-f96755947-dgj7z   1/1     Running   0          5m19s\n\nNAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE\nservice/game-2048   ClusterIP   10.245.120.202   <none>        8080/TCP    5m21s\n\nNAME                        READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/game-2048   1/1     1            1           5m22s\n\nNAME                                  DESIRED   CURRENT   READY   AGE\nreplicaset.apps/game-2048-f96755947   1         1         1       5m22s\n```\n\nFinally, port-forward the `game-2048` service using `kubectl`:\n\n```shell\nkubectl port-forward service/game-2048 -n game-2048 8080:8080\n```\n\nOpen a web browser and point to [localhost:8080](http://localhost:8080/). You should see the `game-2048` welcome page:\n\n![2048 Game Welcome Page](assets/images/game-2048-welcome-page.png)\n\n## Cleaning Up\n\nTo clean up all Kubernetes resources created by the 2048 game application, below command must be used:\n\n```shell\nkubectl delete ns game-2048\n```\n\n**Note:**\n\nKubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k game-2048-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail.\n"
  },
  {
    "path": "game-2048-example/Tiltfile",
    "content": "os.putenv('DOCKER_DEFAULT_PLATFORM', 'linux/amd64')\n\nk8s_yaml(kustomize('kustomize'))\n\ndocker_build('game-2048', '.')\n\nk8s_resource('game-2048', port_forwards='8080')\n"
  },
  {
    "path": "game-2048-example/knative-service.yaml",
    "content": "apiVersion: serving.knative.dev/v1\nkind: Service\nmetadata:\n  name: game-2048\nspec:\n  template:\n    spec:\n      containers:\n        # Replace with your docker registry info\n        - image: registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game:latest\n          ports:\n            - containerPort: 80\n"
  },
  {
    "path": "game-2048-example/kustomize/kustomization.yaml",
    "content": "## 2048 Game Sample Application Kustomization\n\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Making sure all resources used in this tutorial are created in a dedicated namespace\n# Also specific annotations are added for later identification\nnamespace: game-2048\ncommonAnnotations:\n  provider: kubernetes-sample-apps\n\n# 2048 game resources (namespace, services, deployments, etc)\nresources:\n  - resources/namespace.yaml\n  - resources/deployment.yaml\n  - resources/service.yaml\n"
  },
  {
    "path": "game-2048-example/kustomize/resources/deployment.yaml",
    "content": "---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: game-2048\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: game-2048\n  strategy:\n    type: RollingUpdate\n  template:\n    metadata:\n      labels:\n        app: game-2048\n    spec:\n      containers:\n        - name: backend\n          # Replace the `<>` placeholders with your docker registry info\n          image: registry.digitalocean.com/<YOUR_DOCKER_REGISTRY_NAME_HERE>/2048-game:latest\n          ports:\n            - name: http\n              containerPort: 8080\n          resources:\n            requests:\n              cpu: 200m\n              memory: 100Mi\n            limits:\n              cpu: 300m\n              memory: 200Mi\n          # securityContext:\n          #   readOnlyRootFilesystem: true\n          #   runAsNonRoot: true\n          #   allowPrivilegeEscalation: false\n          #   capabilities:\n          #     drop:\n          #       - all\n"
  },
  {
    "path": "game-2048-example/kustomize/resources/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: game-2048\n"
  },
  {
    "path": "game-2048-example/kustomize/resources/service.yaml",
    "content": "apiVersion: v1\nkind: Service\nmetadata:\n  name: game-2048\nspec:\n  ports:\n    - name: http\n      port: 8080\n      targetPort: 8080\n  selector:\n    app: game-2048\n"
  },
  {
    "path": "game-2048-example/package.json",
    "content": "{\n  \"name\": \"knative-example\",\n  \"version\": \"0.0.1\",\n  \"private\": true,\n  \"scripts\": {\n    \"start\": \"webpack server --config webpack.config.js --mode development\",\n    \"build\": \"webpack\",\n    \"build-dev\": \"webpack --mode development\",\n    \"build-prod\": \"webpack --mode production\",\n    \"test\": \"echo '=== DUMMY TEST ==='\"\n  },\n  \"dependencies\": {\n    \"game-2048\": \"^0.0.7\"\n  },\n  \"devDependencies\": {\n    \"css-loader\": \"^6.7.1\",\n    \"html-webpack-plugin\": \"^5.5.0\",\n    \"style-loader\": \"^3.3.1\",\n    \"webpack\": \"^5.72.1\",\n    \"webpack-cli\": \"^4.9.2\",\n    \"webpack-dev-server\": \"^4.9.0\"\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"description\": \"Sample 2048 Game App\"\n}\n"
  },
  {
    "path": "game-2048-example/src/index.js",
    "content": "import 'game-2048/style/main.css';\nimport Game from 'game-2048';\n\nvar gameContainerDiv = document.createElement('div');\ngameContainerDiv.setAttribute('id', 'game-container');\ngameContainerDiv.className = 'container';\ndocument.body.appendChild(gameContainerDiv);\n\nconst game = new Game({\n  gameContainer: gameContainerDiv\n}); \n"
  },
  {
    "path": "game-2048-example/webpack.config.js",
    "content": "const path = require('path');\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\n\nmodule.exports = {\n    mode: process.env.NODE_ENV || 'none',\n    module: {\n        rules: [\n            {\n                test: /\\.css$/i,\n                use: [\"style-loader\", \"css-loader\"],\n            },\n        ],\n    },\n    entry: './src/index.js',\n    output: {\n        filename: 'lib/bundle.js',\n        path: path.resolve(__dirname, 'dist'),\n        clean: true,\n    },\n    plugins: [\n        new HtmlWebpackPlugin({\n            title: '2048 Game',\n        })\n    ],\n    devServer: {\n        static: {\n            directory: path.join(__dirname, 'dist'),\n        },\n        compress: true,\n        port: 8080,\n    },\n};\n"
  },
  {
    "path": "microservices-demo/.gitignore",
    "content": "# macOS\n.DS_Store\n\n# Tilt settings\n/tilt_config.json\n"
  },
  {
    "path": "microservices-demo/CODE_OF_CONDUCT.md",
    "content": "# Contributor Code of Conduct\n\nAs contributors and maintainers of this project,\nand in the interest of fostering an open and welcoming community,\nwe pledge to respect all people who contribute through reporting issues,\nposting feature requests, updating documentation,\nsubmitting pull requests or patches, and other activities.\n\nWe are committed to making participation in this project\na harassment-free experience for everyone,\nregardless of level of experience, gender, gender identity and expression,\nsexual orientation, disability, personal appearance,\nbody size, race, ethnicity, age, religion, or nationality.\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery\n* Personal attacks\n* Trolling or insulting/derogatory comments\n* Public or private harassment\n* Publishing other's private information,\nsuch as physical or electronic\naddresses, without explicit permission\n* Other unethical or unprofessional conduct.\n\nProject maintainers have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct.\nBy adopting this Code of Conduct,\nproject maintainers commit themselves to fairly and consistently\napplying these principles to every aspect of managing this project.\nProject maintainers who do not follow or enforce the Code of Conduct\nmay be permanently removed from the project team.\n\nThis code of conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community.\n\nInstances of abusive, harassing, or otherwise unacceptable behavior\nmay be reported by opening an issue\nor contacting one or more of the project maintainers.\n\nThis Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0,\navailable at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)\n"
  },
  {
    "path": "microservices-demo/CONTRIBUTING.md",
    "content": "# How to Contribute\n\nWe'd love to accept your patches and contributions to this project. There are\njust a few small guidelines you need to follow.\n\n## Development Principles (for Googlers)\n\nThere are a few principles for developing or refactoring the service\nimplementations. Read the [Development Principles\nGuide](./docs/development-principles.md).\n\n## Contributor License Agreement\n\nContributions to this project must be accompanied by a Contributor License\nAgreement. You (or your employer) retain the copyright to your contribution;\nthis simply gives us permission to use and redistribute your contributions as\npart of the project. Head over to <https://cla.developers.google.com/> to see\nyour current agreements on file or to sign a new one.\n\nYou generally only need to submit a CLA once, so if you've already submitted one\n(even if it was for a different project), you probably don't need to do it\nagain.\n\n## Code reviews\n\nAll submissions, including submissions by project members, require review. We\nuse GitHub pull requests for this purpose. Consult\n[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more\ninformation on using pull requests.\n\n## Community Guidelines\n\nThis project follows [Google's Open Source Community\nGuidelines](https://opensource.google.com/conduct/).\n"
  },
  {
    "path": "microservices-demo/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "microservices-demo/README.md",
    "content": "# Overview\n\n**Note:**\n\n**This demo application serves as a companion for the [Kubernetes Adoption Journey](https://digitalocean.github.io/k8s-adoption-journey/) project. Please follow the Kubernetes adoption journey project for more information and comprehensive guidelines.**\n\nThis application is a clone of this [GoogleCloudPlatform](https://github.com/GoogleCloudPlatform/microservices-demo) project. It will be used as a demo for the K8s adoption journey. This clone of the project has been stripped down to focus only on the major parts as required by the adoption journey.\n\n## Prerequisites\n\n1. [Tilt](https://tilt.dev/) installed on your local machine.\n2. [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed on your local machine, with built-in Kubernetes cluster enabled and running.\n\n## Quick Start\n\n1. Run the following command in the project root directory to deploy the **microservices-demo** app to your local Kubernetes cluster:\n\n    ```shell\n    cp tilt-resources/local/tilt_config.json .\n    tilt up\n    ```\n\n2. Open Tilt [web interface](http://localhost:10350/), and wait for all services to be ready.\n3. Access the [web frontend](http://localhost:9090/) in a browser.\n\n## Cleaning Up\n\nRun following command from this project root directory to clean up all resources:\n\n```shell\ntilt down\n```\n"
  },
  {
    "path": "microservices-demo/Tiltfile",
    "content": "#########################################################################\n#\n#   Tiltfile logic\n#\n#########################################################################\n\n\n# Import required functions from Tilt extensions\n\nload(\n    \"ext://namespace\", \n    \"namespace_create\",\n    \"namespace_inject\"\n)\n\n# Import settings from tilt_config.json\nif not os.path.exists(\"./tilt_config.json\"):\n    fail(\n        \"\"\"\n        # ================================================ #\n        # Tilt config file not found in current directory! #\n        # Please copy a template from tilt-resources dir.  #\n        #                                                  #\n        # E.g.:                                            #\n        #    cp tilt-resources/local/tilt_config.json .    #\n        # ================================================ #\n        \"\"\"\n    )\n\nconfig.define_string_list(\"allowed_contexts\")\nconfig.define_string(\"default_registry\")\nconfig.define_string(\"environment\")\nconfig.define_string_list(\"microservices\")\nconfig.define_string(\"namespace\")\nconfig.define_string_list(\"port_forwards\")\ncfg = config.parse()\n\n# Compatibilty setting for ARM arch\nos.putenv(\"DOCKER_DEFAULT_PLATFORM\", \"linux/amd64\")\n\n# Allow default K8S context as stated in the tilt_config.json file\nallow_k8s_contexts(cfg.get(\"allowed_contexts\"))\n\n# Set default registry as stated in the tilt_config.json file\nif cfg.get(\"default_registry\") != \"\":\n    default_registry(cfg.get(\"default_registry\"))\n\n# Build each microservice image as stated in the tilt_config.json file\nfor microservice in cfg.get(\"microservices\"):\n    if \"redis\" in microservice:\n        continue\n    docker_build(\n        microservice,\n        # cartservice is an exception regarding source folder path\n        \"src/{}/src\".format(microservice) if \"cartservice\" in microservice else \"src/{}\".format(microservice)\n    )\n\n# Create namespace as stated in the tilt_config.json file\nnamespace_create(cfg.get(\"namespace\"))\n\n# Deploy each microservice as stated in the tilt_config.json file\nfor microservice in cfg.get(\"microservices\"):\n    k8s_yaml(\n        namespace_inject(\n            read_file(\"kustomize/base/{}.yaml\".format(microservice)), \n            cfg.get(\"namespace\")\n        )\n    )\n\n# Port forwards as stated in the tilt_config.json file\nfor port_forward in cfg.get(\"port_forwards\"):\n    mapping = port_forward.split(\":\")\n    if (len(mapping) != 2):\n        fail(\n            \"\"\"\n            # =================================================== #\n            # Invalid port forward specified in tilt_config.json! #\n            # Should be <resource>:<port_number>.                 #\n            #                                                     #\n            # E.g.: frontend:9090                                 #\n            # =================================================== #\n            \"\"\"\n        )\n    service = mapping[0]\n    port = mapping[1]\n    k8s_resource(service, port_forwards=port)\n"
  },
  {
    "path": "microservices-demo/kustomize/base/cartservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: cartservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: cartservice\n  template:\n    metadata:\n      labels:\n        app: cartservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: cartservice:latest\n          ports:\n            - containerPort: 7070\n          env:\n            - name: REDIS_ADDR\n              value: \"redis-cart:6379\"\n          resources:\n            requests:\n              cpu: 200m\n              memory: 128Mi\n            limits:\n              cpu: 300m\n              memory: 256Mi\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 20\n            exec:\n              command:\n                [\n                  \"/bin/grpc_health_probe\",\n                  \"-addr=:7070\",\n                  \"-rpc-timeout=10s\",\n                  \"-connect-timeout=10s\",\n                ]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 20\n            periodSeconds: 15\n            exec:\n              command:\n                [\n                  \"/bin/grpc_health_probe\",\n                  \"-addr=:7070\",\n                  \"-rpc-timeout=10s\",\n                  \"-connect-timeout=10s\",\n                ]\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: cartservice\nspec:\n  type: ClusterIP\n  selector:\n    app: cartservice\n  ports:\n    - name: grpc\n      port: 7070\n      targetPort: 7070\n"
  },
  {
    "path": "microservices-demo/kustomize/base/checkoutservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: checkoutservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: checkoutservice\n  template:\n    metadata:\n      labels:\n        app: checkoutservice\n    spec:\n      serviceAccountName: default\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: checkoutservice:latest\n          ports:\n            - containerPort: 5050\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:5050\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:5050\"]\n          env:\n            - name: PORT\n              value: \"5050\"\n            - name: PRODUCT_CATALOG_SERVICE_ADDR\n              value: \"productcatalogservice:3550\"\n            - name: SHIPPING_SERVICE_ADDR\n              value: \"shippingservice:50051\"\n            - name: PAYMENT_SERVICE_ADDR\n              value: \"paymentservice:50051\"\n            - name: EMAIL_SERVICE_ADDR\n              value: \"emailservice:5000\"\n            - name: CURRENCY_SERVICE_ADDR\n              value: \"currencyservice:7000\"\n            - name: CART_SERVICE_ADDR\n              value: \"cartservice:7070\"\n            - name: DISABLE_STATS\n              value: \"1\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n          # - name: JAEGER_SERVICE_ADDR\n          #   value: \"jaeger-collector:14268\"\n          resources:\n            requests:\n              cpu: 100m\n              memory: 64Mi\n            limits:\n              cpu: 200m\n              memory: 128Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: checkoutservice\nspec:\n  type: ClusterIP\n  selector:\n    app: checkoutservice\n  ports:\n    - name: grpc\n      port: 5050\n      targetPort: 5050\n"
  },
  {
    "path": "microservices-demo/kustomize/base/currencyservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: currencyservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: currencyservice\n  template:\n    metadata:\n      labels:\n        app: currencyservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: currencyservice:latest\n          ports:\n            - name: grpc\n              containerPort: 7000\n          env:\n            - name: PORT\n              value: \"7000\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n            - name: DISABLE_DEBUGGER\n              value: \"1\"\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:7000\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:7000\"]\n          resources:\n            requests:\n              cpu: 100m\n              memory: 128Mi\n            limits:\n              cpu: 200m\n              memory: 256Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: currencyservice\nspec:\n  type: ClusterIP\n  selector:\n    app: currencyservice\n  ports:\n    - name: grpc\n      port: 7000\n      targetPort: 7000\n"
  },
  {
    "path": "microservices-demo/kustomize/base/emailservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: emailservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: emailservice\n  template:\n    metadata:\n      labels:\n        app: emailservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: emailservice:latest\n          ports:\n            - containerPort: 8080\n          env:\n            - name: PORT\n              value: \"8080\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n          readinessProbe:\n            timeoutSeconds: 15\n            periodSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:8080\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            periodSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:8080\"]\n          resources:\n            requests:\n              cpu: 100m\n              memory: 128Mi\n            limits:\n              cpu: 200m\n              memory: 256Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: emailservice\nspec:\n  type: ClusterIP\n  selector:\n    app: emailservice\n  ports:\n    - name: grpc\n      port: 5000\n      targetPort: 8080\n"
  },
  {
    "path": "microservices-demo/kustomize/base/frontend.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: frontend\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: frontend\n  template:\n    metadata:\n      labels:\n        app: frontend\n    spec:\n      serviceAccountName: default\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: frontend:latest\n          ports:\n            - containerPort: 8080\n          readinessProbe:\n            initialDelaySeconds: 10\n            httpGet:\n              path: \"/_healthz\"\n              port: 8080\n              httpHeaders:\n                - name: \"Cookie\"\n                  value: \"shop_session-id=x-readiness-probe\"\n          livenessProbe:\n            initialDelaySeconds: 10\n            httpGet:\n              path: \"/_healthz\"\n              port: 8080\n              httpHeaders:\n                - name: \"Cookie\"\n                  value: \"shop_session-id=x-liveness-probe\"\n          env:\n            - name: PORT\n              value: \"8080\"\n            - name: PRODUCT_CATALOG_SERVICE_ADDR\n              value: \"productcatalogservice:3550\"\n            - name: CURRENCY_SERVICE_ADDR\n              value: \"currencyservice:7000\"\n            - name: CART_SERVICE_ADDR\n              value: \"cartservice:7070\"\n            - name: RECOMMENDATION_SERVICE_ADDR\n              value: \"recommendationservice:8080\"\n            - name: SHIPPING_SERVICE_ADDR\n              value: \"shippingservice:50051\"\n            - name: CHECKOUT_SERVICE_ADDR\n              value: \"checkoutservice:5050\"\n            - name: AD_SERVICE_ADDR\n              value: \"adservice:9555\"\n            # # ENV_PLATFORM: One of: local, gcp, aws, azure, onprem, alibaba\n            # # When not set, defaults to \"local\" unless running in GKE, otherwies auto-sets to gcp\n            # - name: ENV_PLATFORM\n            #   value: \"local\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n          resources:\n            requests:\n              cpu: 100m\n              memory: 64Mi\n            limits:\n              cpu: 200m\n              memory: 128Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: frontend\nspec:\n  type: ClusterIP\n  selector:\n    app: frontend\n  ports:\n    - name: http\n      port: 80\n      targetPort: 8080\n"
  },
  {
    "path": "microservices-demo/kustomize/base/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - namespace.yaml\n  - cartservice.yaml\n  - checkoutservice.yaml\n  - currencyservice.yaml\n  - emailservice.yaml\n  - frontend.yaml\n  - paymentservice.yaml\n  - productcatalogservice.yaml\n  - recommendationservice.yaml\n  - redis.yaml\n  - shippingservice.yaml\n"
  },
  {
    "path": "microservices-demo/kustomize/base/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: microservices-demo\n"
  },
  {
    "path": "microservices-demo/kustomize/base/paymentservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: paymentservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: paymentservice\n  template:\n    metadata:\n      labels:\n        app: paymentservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: paymentservice:latest\n          ports:\n            - containerPort: 50051\n          env:\n            - name: PORT\n              value: \"50051\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n            - name: DISABLE_DEBUGGER\n              value: \"1\"\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:50051\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-rpc-timeout=5s\", \"-addr=:50051\"]\n          resources:\n            requests:\n              cpu: 100m\n              memory: 128Mi\n            limits:\n              cpu: 200m\n              memory: 256Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: paymentservice\nspec:\n  type: ClusterIP\n  selector:\n    app: paymentservice\n  ports:\n    - name: grpc\n      port: 50051\n      targetPort: 50051\n"
  },
  {
    "path": "microservices-demo/kustomize/base/productcatalogservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: productcatalogservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: productcatalogservice\n  template:\n    metadata:\n      labels:\n        app: productcatalogservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: productcatalogservice:latest\n          ports:\n            - containerPort: 3550\n          env:\n            - name: PORT\n              value: \"3550\"\n            - name: DISABLE_STATS\n              value: \"1\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n          # - name: JAEGER_SERVICE_ADDR\n          #   value: \"jaeger-collector:14268\"\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:3550\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:3550\"]\n          resources:\n            requests:\n              cpu: 100m\n              memory: 64Mi\n            limits:\n              cpu: 200m\n              memory: 128Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: productcatalogservice\nspec:\n  type: ClusterIP\n  selector:\n    app: productcatalogservice\n  ports:\n    - name: grpc\n      port: 3550\n      targetPort: 3550\n"
  },
  {
    "path": "microservices-demo/kustomize/base/recommendationservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: recommendationservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: recommendationservice\n  template:\n    metadata:\n      labels:\n        app: recommendationservice\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: recommendationservice:latest\n          ports:\n            - containerPort: 8080\n          readinessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            periodSeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:8080\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            periodSeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:8080\"]\n          env:\n            - name: PORT\n              value: \"8080\"\n            - name: PRODUCT_CATALOG_SERVICE_ADDR\n              value: \"productcatalogservice:3550\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n            - name: DISABLE_DEBUGGER\n              value: \"1\"\n          resources:\n            requests:\n              cpu: 100m\n              memory: 220Mi\n            limits:\n              cpu: 200m\n              memory: 450Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: recommendationservice\nspec:\n  type: ClusterIP\n  selector:\n    app: recommendationservice\n  ports:\n    - name: grpc\n      port: 8080\n      targetPort: 8080\n"
  },
  {
    "path": "microservices-demo/kustomize/base/redis.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: redis-cart\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: redis-cart\n  template:\n    metadata:\n      labels:\n        app: redis-cart\n    spec:\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: redis\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          image: redis:alpine\n          ports:\n            - containerPort: 6379\n          readinessProbe:\n            periodSeconds: 5\n            tcpSocket:\n              port: 6379\n          livenessProbe:\n            periodSeconds: 5\n            tcpSocket:\n              port: 6379\n          volumeMounts:\n            - mountPath: /data\n              name: redis-data\n          resources:\n            limits:\n              memory: 256Mi\n              cpu: 125m\n            requests:\n              cpu: 70m\n              memory: 200Mi\n      volumes:\n        - name: redis-data\n          emptyDir: {}\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: redis-cart\nspec:\n  type: ClusterIP\n  selector:\n    app: redis-cart\n  ports:\n    - name: tls-redis\n      port: 6379\n      targetPort: 6379\n"
  },
  {
    "path": "microservices-demo/kustomize/base/shippingservice.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: shippingservice\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: shippingservice\n  template:\n    metadata:\n      labels:\n        app: shippingservice\n    spec:\n      serviceAccountName: default\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      containers:\n        - name: server\n          securityContext:\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop:\n                - all\n            privileged: false\n            readOnlyRootFilesystem: true\n          imagePullPolicy: Always\n          image: shippingservice:latest\n          ports:\n            - containerPort: 50051\n          env:\n            - name: PORT\n              value: \"50051\"\n            - name: DISABLE_STATS\n              value: \"1\"\n            - name: DISABLE_TRACING\n              value: \"1\"\n            - name: DISABLE_PROFILER\n              value: \"1\"\n          # - name: JAEGER_SERVICE_ADDR\n          #   value: \"jaeger-collector:14268\"\n          readinessProbe:\n            timeoutSeconds: 15\n            periodSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:50051\"]\n          livenessProbe:\n            timeoutSeconds: 15\n            initialDelaySeconds: 15\n            exec:\n              command: [\"/bin/grpc_health_probe\", \"-addr=:50051\"]\n          resources:\n            requests:\n              cpu: 100m\n              memory: 64Mi\n            limits:\n              cpu: 200m\n              memory: 128Mi\n\n---\napiVersion: v1\nkind: Service\nmetadata:\n  name: shippingservice\nspec:\n  type: ClusterIP\n  selector:\n    app: shippingservice\n  ports:\n    - name: grpc\n      port: 50051\n      targetPort: 50051\n"
  },
  {
    "path": "microservices-demo/kustomize/dev/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: microservices-demo-dev\ncommonLabels:\n  variant: dev\n\nresources:\n  - ../base\n\nimages:\n  - name: cartservice\n    newName: registry.digitalocean.com/microservices-demo/cartservice\n    newTag: v1.0.0\n  - name: checkoutservice\n    newName: registry.digitalocean.com/microservices-demo/checkoutservice\n    newTag: v1.0.0\n  - name: currencyservice\n    newName: registry.digitalocean.com/microservices-demo/currencyservice\n    newTag: v1.0.0\n  - name: emailservice\n    newName: registry.digitalocean.com/microservices-demo/emailservice\n    newTag: v1.0.0\n  - name: frontend\n    newName: registry.digitalocean.com/microservices-demo/frontend\n    newTag: v1.0.0\n  - name: paymentservice\n    newName: registry.digitalocean.com/microservices-demo/paymentservice\n    newTag: v1.0.0\n  - name: productcatalogservice\n    newName: registry.digitalocean.com/microservices-demo/productcatalogservice\n    newTag: v1.0.0\n  - name: recommendationservice\n    newName: registry.digitalocean.com/microservices-demo/recommendationservice\n    newTag: v1.0.0\n  - name: shippingservice\n    newName: registry.digitalocean.com/microservices-demo/shippingservice\n    newTag: v1.0.0\n"
  },
  {
    "path": "microservices-demo/kustomize/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nresources:\n  - dev\n  - staging\n  - prod\n"
  },
  {
    "path": "microservices-demo/kustomize/prod/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: microservices-demo-prod\ncommonLabels:\n  variant: prod\n\nresources:\n  - ../base\n\nimages:\n  - name: cartservice\n    newName: registry.digitalocean.com/microservices-demo/cartservice\n    newTag: v1.0.0\n  - name: checkoutservice\n    newName: registry.digitalocean.com/microservices-demo/checkoutservice\n    newTag: v1.0.0\n  - name: currencyservice\n    newName: registry.digitalocean.com/microservices-demo/currencyservice\n    newTag: v1.0.0\n  - name: emailservice\n    newName: registry.digitalocean.com/microservices-demo/emailservice\n    newTag: v1.0.0\n  - name: frontend\n    newName: registry.digitalocean.com/microservices-demo/frontend\n    newTag: v1.0.0\n  - name: paymentservice\n    newName: registry.digitalocean.com/microservices-demo/paymentservice\n    newTag: v1.0.0\n  - name: productcatalogservice\n    newName: registry.digitalocean.com/microservices-demo/productcatalogservice\n    newTag: v1.0.0\n  - name: recommendationservice\n    newName: registry.digitalocean.com/microservices-demo/recommendationservice\n    newTag: v1.0.0\n  - name: shippingservice\n    newName: registry.digitalocean.com/microservices-demo/shippingservice\n    newTag: v1.0.0\n\nreplicas:\n  - name: cartservice\n    count: 2\n  - name: checkoutservice\n    count: 2\n  - name: currencyservice\n    count: 2\n  - name: emailservice\n    count: 2\n  - name: frontend\n    count: 2\n  - name: paymentservice\n    count: 2\n  - name: productcatalogservice\n    count: 2\n  - name: recommendationservice\n    count: 2\n  - name: shippingservice\n    count: 2\n"
  },
  {
    "path": "microservices-demo/kustomize/staging/kustomization.yaml",
    "content": "apiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\nnamespace: microservices-demo-staging\ncommonLabels:\n  variant: staging\n\nresources:\n  - ../base\n\nimages:\n  - name: cartservice\n    newName: registry.digitalocean.com/microservices-demo/cartservice\n    newTag: v1.0.0\n  - name: checkoutservice\n    newName: registry.digitalocean.com/microservices-demo/checkoutservice\n    newTag: v1.0.0\n  - name: currencyservice\n    newName: registry.digitalocean.com/microservices-demo/currencyservice\n    newTag: v1.0.0\n  - name: emailservice\n    newName: registry.digitalocean.com/microservices-demo/emailservice\n    newTag: v1.0.0\n  - name: frontend\n    newName: registry.digitalocean.com/microservices-demo/frontend\n    newTag: v1.0.0\n  - name: paymentservice\n    newName: registry.digitalocean.com/microservices-demo/paymentservice\n    newTag: v1.0.0\n  - name: productcatalogservice\n    newName: registry.digitalocean.com/microservices-demo/productcatalogservice\n    newTag: v1.0.0\n  - name: recommendationservice\n    newName: registry.digitalocean.com/microservices-demo/recommendationservice\n    newTag: v1.0.0\n  - name: shippingservice\n    newName: registry.digitalocean.com/microservices-demo/shippingservice\n    newTag: v1.0.0\n  \nreplicas:\n  - name: cartservice\n    count: 2\n  - name: checkoutservice\n    count: 2\n  - name: currencyservice\n    count: 2\n  - name: emailservice\n    count: 2\n  - name: frontend\n    count: 2\n  - name: paymentservice\n    count: 2\n  - name: productcatalogservice\n    count: 2\n  - name: recommendationservice\n    count: 2\n  - name: shippingservice\n    count: 2\n"
  },
  {
    "path": "microservices-demo/release-scripts/README.md",
    "content": "# Overview of the Release Scripts\n\nThis directory contains the scripts for creating a new `microservices-demo` release.\n\n## Create a New Release\n\n### 1. Decide on the next release version number using [semantic versioning](https://semver.org/).\n\n- Look at the [commits since the previous release](https://github.com/GoogleCloudPlatform/microservices-demo/commits/main).\n\n#### 2. Open a new terminal\n\n#### 3. Make sure you have `gsed` installed. If not, `brew install gnu-sed`.\n\n#### 4. Set the following environment variables\n\n- `TAG` - This is the new version (e.g., `v0.3.5`).\n- `REPO_PREFIX` - This is the Docker repository.\n\n##### Example\n\n```shell\nexport TAG=v0.3.5\nexport REPO_PREFIX=gcr.io/google-samples/microservices-demo\n```\n\n#### 5. Run `./release-scripts/make-release.sh`\n\n- Make sure you run `./hack/make-release.sh` from this project's root folder — **not** from inside the `release-scripts/` folder.\n- This script:\n  1. uses `make-docker-images.sh` to build and push a Docker image for each microservice to the previously specified repository.\n  1. uses `make-release-artifacts.sh` to regenerates (and update the image $TAGS) YAML file at `./release/kubernetes-manifests.yaml`.\n  1. runs `git tag` and pushes a new branch (e.g., `release/v0.3.5`) with the changes to `release/kubernetes-manifests.yaml`.\n\n#### 6. [Draft a new release on GitHub](https://github.com/GoogleCloudPlatform/microservices-demo/releases).\n\n- Summarize the [commits since the previous release](https://github.com/GoogleCloudPlatform/microservices-demo/commits/main).\n- See previous releases for inspiration on release notes.\n\n#### 7. Create a new pull-request\n\n- When you ran `make-release.sh`, it created a new branch (e.g., `release/v0.3.5`).\n- Include the new release draft in the pull-request description for reviewers to see.\n\n#### 8. Once your pull-request is approved, merge it\n\n#### 9. Deploy `release/kubernetes-manifests.yaml`\n\n```shell\nkubectl apply -f ./release/kubernetes-manifests.yaml\n```\n"
  },
  {
    "path": "microservices-demo/release-scripts/license_header.txt",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n"
  },
  {
    "path": "microservices-demo/release-scripts/make-cnb-docker-images.sh",
    "content": "#!/usr/bin/env bash\n\nset -euo pipefail\nSCRIPTDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n\nlog() { echo \"$1\" >&2; }\n\nTAG=\"${TAG:?TAG env variable must be specified}\"\nREPO_PREFIX=\"${REPO_PREFIX:?REPO_PREFIX env variable must be specified}\"\n\nwhile IFS= read -d $'\\0' -r dir; do\n    # build image\n    svcname=\"$(basename \"${dir}\")\"\n    builddir=\"${dir}\"\n    #PR 516 moved cartservice build artifacts one level down to src\n    if [ $svcname == \"cartservice\" ] \n    then\n        builddir=\"${dir}/src\"\n    fi\n    ## skipping loadgenerator service building as it's used only in CI for tests\n    if [ $svcname == \"loadgenerator\" ]\n    then \n        continue\n    fi\n    image=\"${REPO_PREFIX}/$svcname:$TAG\"\n    (\n        cd \"${builddir}\"\n        log \"Building and pushing: ${image}\"\n        ## we are not using the --publish pack flag due to an issue preventing the pack CLI from pushing to DOCR\n        pack build ${image} --builder gcr.io/buildpacks/builder:v1\n        docker push ${image}\n    )\ndone < <(find \"${SCRIPTDIR}/../src\" -mindepth 1 -maxdepth 1 -type d -print0)\n\nlog \"Successfully built and pushed all images.\"\n"
  },
  {
    "path": "microservices-demo/release-scripts/make-docker-images.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2019 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Builds and pushes docker image for each demo microservice.\n\nset -euo pipefail\nSCRIPTDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n\nlog() { echo \"$1\" >&2; }\n\nTAG=\"${TAG:?TAG env variable must be specified}\"\nREPO_PREFIX=\"${REPO_PREFIX:?REPO_PREFIX env variable must be specified}\"\n\nwhile IFS= read -d $'\\0' -r dir; do\n    # build image\n    svcname=\"$(basename \"${dir}\")\"\n    builddir=\"${dir}\"\n    #PR 516 moved cartservice build artifacts one level down to src\n    if [ $svcname == \"cartservice\" ] \n    then\n        builddir=\"${dir}/src\"\n    fi\n    image=\"${REPO_PREFIX}/$svcname:$TAG\"\n    (\n        cd \"${builddir}\"\n        log \"Building and pushing: ${image}\"\n        docker buildx build --platform linux/amd64 -t \"${image}\" --push .\n    )\ndone < <(find \"${SCRIPTDIR}/../src\" -mindepth 1 -maxdepth 1 -type d -print0)\n\nlog \"Successfully built and pushed all images.\"\n"
  },
  {
    "path": "microservices-demo/release-scripts/make-release-artifacts.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2019 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# This script compiles manifest files with the image tags and places them in\n# /release/...\n\nset -euo pipefail\nSCRIPTDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n[[ -n \"${DEBUG:-}\" ]] && set -x\n\nlog() { echo \"$1\" >&2; }\n\nTAG=\"${TAG:?TAG env variable must be specified}\"\nREPO_PREFIX=\"${REPO_PREFIX:?REPO_PREFIX env variable must be specified}\"\nOUT_DIR=\"${OUT_DIR:-${SCRIPTDIR}/../release}\"\n\nprint_license_header() {\n    cat \"${SCRIPTDIR}/license_header.txt\"\n    echo\n}\n\nprint_autogenerated_warning() {\n    cat<<EOF\n# ----------------------------------------------------------\n# WARNING: This file is autogenerated. Do not manually edit.\n# ----------------------------------------------------------\n\nEOF\n}\n\n# define gsed as a function on Linux for compatibility\n[ \"$(uname -s)\" == \"Linux\" ] && gsed() {\n    sed \"$@\"\n}\n\nread_manifests() {\n    local dir\n    dir=\"$1\"\n\n    while IFS= read -d $'\\0' -r file; do\n        echo \"---\"\n        \n        # strip license headers (pattern \"^# \")\n        awk '\n        /^[^# ]/ { found = 1 }\n        found { print }' \"${file}\"\n    done < <(find \"${dir}\" -name '*.yaml' -type f -print0)\n}\n\nmk_kubernetes_manifests() {\n    out_manifest=\"$(read_manifests \"${SCRIPTDIR}/../kubernetes-manifests\")\"\n\n    # replace \"image\" repo, tag for each service\n    for dir in ./src/*/\n    do\n        svcname=\"$(basename \"${dir}\")\"\n        image=\"$REPO_PREFIX/$svcname:$TAG\"\n\n        pattern=\"^(\\s*)image:\\s.*$svcname(.*)(\\s*)\"\n        replace=\"\\1image: $image\\3\"\n        out_manifest=\"$(gsed -r \"s|$pattern|$replace|g\" <(echo \"${out_manifest}\") )\"\n    done\n\n    print_license_header\n    print_autogenerated_warning\n    echo '# [START gke_release_kubernetes_manifests_microservices_demo]'\n    echo \"${out_manifest}\"\n    echo \"# [END gke_release_kubernetes_manifests_microservices_demo]\"\n}\n\nmk_istio_manifests() {\n    print_license_header\n    print_autogenerated_warning\n    echo '# [START servicemesh_release_istio_manifests_microservices_demo]'\n    read_manifests \"${SCRIPTDIR}/../istio-manifests\"\n    echo '# [END servicemesh_release_istio_manifests_microservices_demo]'\n}\n\nmain() {\n    mkdir -p \"${OUT_DIR}\"\n    local k8s_manifests_file istio_manifests_file\n\n    k8s_manifests_file=\"${OUT_DIR}/kubernetes-manifests.yaml\"\n    mk_kubernetes_manifests > \"${k8s_manifests_file}\"\n    log \"Written ${k8s_manifests_file}\"\n\n    istio_manifests_file=\"${OUT_DIR}/istio-manifests.yaml\"\n    mk_istio_manifests > \"${istio_manifests_file}\"\n    log \"Written ${istio_manifests_file}\"\n}\n\nmain\n"
  },
  {
    "path": "microservices-demo/release-scripts/make-release.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright 2019 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# This script creates a new release by:\n# - 1. building/pushing images\n# - 2. injecting tags into YAML manifests\n# - 3. creating a new git tag\n# - 4. pushing the tag/commit to main.\n\nset -euo pipefail\nSCRIPTDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n[[ -n \"${DEBUG:-}\" ]] && set -x\n\nlog() { echo \"$1\" >&2; }\nfail() { log \"$1\"; exit 1; }\n\nTAG=\"${TAG:?TAG env variable must be specified}\"\nREPO_PREFIX=\"${REPO_PREFIX:?REPO_PREFIX env variable must be specified e.g. gcr.io\\/google-samples\\/microservices-demo}\"\n\nif [[ \"$TAG\" != v* ]]; then\n    fail \"\\$TAG must start with 'v', e.g. v0.1.0 (got: $TAG)\"\nfi\n\n# build and push images\n\"${SCRIPTDIR}\"/make-docker-images.sh\n\n# update yaml\n\"${SCRIPTDIR}\"/make-release-artifacts.sh\n\n# create git release / push to new branch\ngit checkout -b \"release/${TAG}\"\ngit add \"${SCRIPTDIR}/../release/\"\ngit commit --allow-empty -m \"Release $TAG\"\nlog \"Pushing k8s manifests to release/${TAG}...\"\ngit tag \"$TAG\"\ngit push --set-upstream origin \"release/${TAG}\"\ngit push --tags\n\nlog \"Successfully tagged release $TAG.\"\n"
  },
  {
    "path": "microservices-demo/src/.gitignore",
    "content": "# Go: for the time being we are not checking in the vendor/ directories to git\n# to prevent the repo from getting larger forever. In each Go service, you can\n# run \"dep ensure --vendor-only\" to download the dependencies to vendor/ based\n# on the Gopkg.{toml,lock} files in that directory.\nvendor/\n"
  },
  {
    "path": "microservices-demo/src/cartservice/.gitignore",
    "content": "**/bin/\n**/obj/\n.vs/*.*\n"
  },
  {
    "path": "microservices-demo/src/cartservice/cartservice.sln",
    "content": "﻿\r\nMicrosoft Visual Studio Solution File, Format Version 12.00\r\n# Visual Studio 15\r\nVisualStudioVersion = 15.0.26124.0\r\nMinimumVisualStudioVersion = 15.0.26124.0\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"cartservice\", \"src\\cartservice.csproj\", \"{2348C29F-E8D3-4955-916D-D609CBC97FCB}\"\r\nEndProject\r\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"cartservice.tests\", \"tests\\cartservice.tests.csproj\", \"{59825342-CE64-4AFA-8744-781692C0811B}\"\r\nEndProject\r\nGlobal\r\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\r\n\t\tDebug|Any CPU = Debug|Any CPU\r\n\t\tDebug|x64 = Debug|x64\r\n\t\tDebug|x86 = Debug|x86\r\n\t\tRelease|Any CPU = Release|Any CPU\r\n\t\tRelease|x64 = Release|x64\r\n\t\tRelease|x86 = Release|x86\r\n\tEndGlobalSection\r\n\tGlobalSection(SolutionProperties) = preSolution\r\n\t\tHideSolutionNode = FALSE\r\n\tEndGlobalSection\r\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{2348C29F-E8D3-4955-916D-D609CBC97FCB}.Release|x86.Build.0 = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|Any CPU.Build.0 = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|x64.ActiveCfg = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|x64.Build.0 = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|x86.ActiveCfg = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Debug|x86.Build.0 = Debug|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|Any CPU.ActiveCfg = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|Any CPU.Build.0 = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|x64.ActiveCfg = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|x64.Build.0 = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|x86.ActiveCfg = Release|Any CPU\r\n\t\t{59825342-CE64-4AFA-8744-781692C0811B}.Release|x86.Build.0 = Release|Any CPU\r\n\tEndGlobalSection\r\nEndGlobal\r\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/.dockerignore",
    "content": "**/*.sh\n**/*.bat\n**/bin/\n**/obj/\n**/out/\nDockerfile*"
  },
  {
    "path": "microservices-demo/src/cartservice/src/Dockerfile",
    "content": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# https://mcr.microsoft.com/v2/dotnet/sdk/tags/list\nFROM mcr.microsoft.com/dotnet/sdk:6.0.400 as builder\nWORKDIR /app\nCOPY cartservice.csproj .\nRUN dotnet restore cartservice.csproj -r linux-musl-x64\nCOPY . .\nRUN dotnet publish cartservice.csproj -p:PublishSingleFile=true -r linux-musl-x64 --self-contained true -p:PublishTrimmed=True -p:TrimMode=Link -c release -o /cartservice --no-restore\n\n# https://mcr.microsoft.com/v2/dotnet/runtime-deps/tags/list\nFROM mcr.microsoft.com/dotnet/runtime-deps:6.0.8-alpine3.16-amd64\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\nWORKDIR /app\nCOPY --from=builder /cartservice .\nENV ASPNETCORE_URLS http://*:7070\nENV DOTNET_EnableDiagnostics=0\nENTRYPOINT [\"/app/cartservice\"]\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/Dockerfile.debug",
    "content": "# Copyright 2021 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM mcr.microsoft.com/dotnet/sdk:7.0 AS build\nWORKDIR /app\nCOPY . .\nRUN dotnet restore cartservice.csproj\nRUN dotnet build \"./cartservice.csproj\" -c Debug -o /out\n\nFROM build AS publish\nRUN dotnet publish cartservice.csproj -c Debug -o /out\n\n# Building final image used in running container\nFROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final\n# Installing procps on the container to enable debugging of .NET Core\nRUN apt-get update \\\n    && apt-get install -y unzip procps wget\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\nWORKDIR /app\nCOPY --from=publish /out .\nENV ASPNETCORE_URLS=http://*:7070\n\nENTRYPOINT [\"dotnet\", \"cartservice.dll\"]\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/Program.cs",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.Hosting;\nusing cartservice;\n\nCreateHostBuilder(args).Build().Run();\n\nstatic IHostBuilder CreateHostBuilder(string[] args) =>\n    Host.CreateDefaultBuilder(args)\n        .ConfigureWebHostDefaults(webBuilder =>\n        {\n            webBuilder.UseStartup<Startup>();\n        });"
  },
  {
    "path": "microservices-demo/src/cartservice/src/Startup.cs",
    "content": "using System;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Diagnostics.HealthChecks;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Diagnostics.HealthChecks;\nusing Microsoft.Extensions.Hosting;\nusing cartservice.cartstore;\nusing cartservice.services;\nusing Microsoft.Extensions.Caching.StackExchangeRedis;\n\nnamespace cartservice\n{\n    public class Startup\n    {\n        public Startup(IConfiguration configuration)\n        {\n            Configuration = configuration;\n        }\n\n        public IConfiguration Configuration { get; }\n        \n        // This method gets called by the runtime. Use this method to add services to the container.\n        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940\n        public void ConfigureServices(IServiceCollection services)\n        {\n            string redisAddress = Configuration[\"REDIS_ADDR\"];\n            if (!string.IsNullOrEmpty(redisAddress))\n            {\n                services.AddStackExchangeRedisCache(options =>\n                {\n                    options.Configuration = redisAddress;\n                });\n            }\n            else\n            {\n                Console.WriteLine(\"Redis cache host(hostname+port) was not specified. Starting a cart service using in memory store\");\n                services.AddDistributedMemoryCache();\n            }\n\n            services.AddSingleton<ICartStore, RedisCartStore>();\n\n            services.AddGrpc();\n        }\n\n        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.\n        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n        {\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n            }\n\n            app.UseRouting();\n\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapGrpcService<CartService>();\n                endpoints.MapGrpcService<cartservice.services.HealthCheckService>();\n\n                endpoints.MapGet(\"/\", async context =>\n                {\n                    await context.Response.WriteAsync(\"Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909\");\n                });\n            });\n        }\n    }\n}"
  },
  {
    "path": "microservices-demo/src/cartservice/src/appsettings.json",
    "content": "{\n    \"Logging\": {\n      \"LogLevel\": {\n        \"Default\": \"Information\",\n        \"Microsoft\": \"Warning\",\n        \"Microsoft.Hosting.Lifetime\": \"Information\"\n      }\n    },\n    \"AllowedHosts\": \"*\",\n    \"Kestrel\": {\n      \"EndpointDefaults\": {\n        \"Protocols\": \"Http2\"\n      }\n    }\n  }"
  },
  {
    "path": "microservices-demo/src/cartservice/src/cartservice.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net6.0</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Grpc.AspNetCore\" Version=\"2.48.0\" />\n    <PackageReference Include=\"Grpc.HealthCheck\" Version=\"2.48.0\" />\n    <PackageReference Include=\"Microsoft.Extensions.Caching.StackExchangeRedis\" Version=\"6.0.8\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Protobuf Include=\"protos\\Cart.proto\" GrpcServices=\"Both\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/cartstore/ICartStore.cs",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System.Threading.Tasks;\n\nnamespace cartservice.cartstore\n{\n    public interface ICartStore\n    {\n        Task AddItemAsync(string userId, string productId, int quantity);\n        Task EmptyCartAsync(string userId);\n        Task<Hipstershop.Cart> GetCartAsync(string userId);\n        bool Ping();\n    }\n}"
  },
  {
    "path": "microservices-demo/src/cartservice/src/cartstore/RedisCartStore.cs",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Grpc.Core;\nusing Microsoft.Extensions.Caching.Distributed;\nusing Google.Protobuf;\n\nnamespace cartservice.cartstore\n{\n    public class RedisCartStore : ICartStore\n    {\n        private readonly IDistributedCache _cache;\n\n        public RedisCartStore(IDistributedCache cache)\n        {\n            _cache = cache;\n        }\n\n        public async Task AddItemAsync(string userId, string productId, int quantity)\n        {\n            Console.WriteLine($\"AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}\");\n\n            try\n            {\n                Hipstershop.Cart cart;\n                var value = await _cache.GetAsync(userId);\n                if (value == null)\n                {\n                    cart = new Hipstershop.Cart();\n                    cart.UserId = userId;\n                    cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity });\n                }\n                else\n                {\n                    cart = Hipstershop.Cart.Parser.ParseFrom(value);\n                    var existingItem = cart.Items.SingleOrDefault(i => i.ProductId == productId);\n                    if (existingItem == null)\n                    {\n                        cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity });\n                    }\n                    else\n                    {\n                        existingItem.Quantity += quantity;\n                    }\n                }\n                await _cache.SetAsync(userId, cart.ToByteArray());\n            }\n            catch (Exception ex)\n            {\n                throw new RpcException(new Status(StatusCode.FailedPrecondition, $\"Can't access cart storage. {ex}\"));\n            }\n        }\n\n        public async Task EmptyCartAsync(string userId)\n        {\n            Console.WriteLine($\"EmptyCartAsync called with userId={userId}\");\n\n            try\n            {\n                var cart = new Hipstershop.Cart();\n                await _cache.SetAsync(userId, cart.ToByteArray());\n            }\n            catch (Exception ex)\n            {\n                throw new RpcException(new Status(StatusCode.FailedPrecondition, $\"Can't access cart storage. {ex}\"));\n            }\n        }\n\n        public async Task<Hipstershop.Cart> GetCartAsync(string userId)\n        {\n            Console.WriteLine($\"GetCartAsync called with userId={userId}\");\n\n            try\n            {\n                // Access the cart from the cache\n                var value = await _cache.GetAsync(userId);\n\n                if (value != null)\n                {\n                    return Hipstershop.Cart.Parser.ParseFrom(value);\n                }\n\n                // We decided to return empty cart in cases when user wasn't in the cache before\n                return new Hipstershop.Cart();\n            }\n            catch (Exception ex)\n            {\n                throw new RpcException(new Status(StatusCode.FailedPrecondition, $\"Can't access cart storage. {ex}\"));\n            }\n        }\n\n        public bool Ping()\n        {\n            try\n            {\n                return true;\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/protos/Cart.proto",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\npackage hipstershop;\n\n// -----------------Cart service-----------------\n\nservice CartService {\n    rpc AddItem(AddItemRequest) returns (Empty) {}\n    rpc GetCart(GetCartRequest) returns (Cart) {}\n    rpc EmptyCart(EmptyCartRequest) returns (Empty) {}\n}\n\nmessage CartItem {\n    string product_id = 1;\n    int32  quantity = 2;\n}\n\nmessage AddItemRequest {\n    string user_id = 1;\n    CartItem item = 2;\n}\n\nmessage EmptyCartRequest {\n    string user_id = 1;\n}\n\nmessage GetCartRequest {\n    string user_id = 1;\n}\n\nmessage Cart {\n    string user_id = 1;\n    repeated CartItem items = 2;\n}\n\nmessage Empty {}\n"
  },
  {
    "path": "microservices-demo/src/cartservice/src/services/CartService.cs",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Threading.Tasks;\nusing Grpc.Core;\nusing Microsoft.Extensions.Logging;\nusing cartservice.cartstore;\nusing Hipstershop;\n\nnamespace cartservice.services\n{\n    public class CartService : Hipstershop.CartService.CartServiceBase\n    {\n        private readonly static Empty Empty = new Empty();\n        private readonly ICartStore _cartStore;\n\n        public CartService(ICartStore cartStore)\n        {\n            _cartStore = cartStore;\n        }\n\n        public async override Task<Empty> AddItem(AddItemRequest request, ServerCallContext context)\n        {\n            await _cartStore.AddItemAsync(request.UserId, request.Item.ProductId, request.Item.Quantity);\n            return Empty;\n        }\n\n        public override Task<Cart> GetCart(GetCartRequest request, ServerCallContext context)\n        {\n            return _cartStore.GetCartAsync(request.UserId);\n        }\n\n        public async override Task<Empty> EmptyCart(EmptyCartRequest request, ServerCallContext context)\n        {\n            await _cartStore.EmptyCartAsync(request.UserId);\n            return Empty;\n        }\n    }\n}"
  },
  {
    "path": "microservices-demo/src/cartservice/src/services/HealthCheckService.cs",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Threading.Tasks;\nusing Grpc.Core;\nusing Grpc.Health.V1;\nusing static Grpc.Health.V1.Health;\nusing cartservice.cartstore;\n\nnamespace cartservice.services\n{\n    internal class HealthCheckService : HealthBase\n    {\n        private ICartStore _cartStore { get; }\n\n        public HealthCheckService (ICartStore cartStore) \n        {\n            _cartStore = cartStore;\n        }\n\n        public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)\n        {\n            Console.WriteLine (\"Checking CartService Health\");\n            return Task.FromResult(new HealthCheckResponse {\n                Status = _cartStore.Ping() ? HealthCheckResponse.Types.ServingStatus.Serving : HealthCheckResponse.Types.ServingStatus.NotServing\n            });\n        }\n    }\n}"
  },
  {
    "path": "microservices-demo/src/cartservice/tests/.gitignore",
    "content": "/bin/*\n/obj/*\n/.vs/*"
  },
  {
    "path": "microservices-demo/src/cartservice/tests/CartServiceTests.cs",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nusing System;\nusing System.Threading.Tasks;\nusing Grpc.Net.Client;\nusing Hipstershop;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.TestHost;\nusing Microsoft.Extensions.Hosting;\nusing Xunit;\nusing static Hipstershop.CartService;\n\nnamespace cartservice.tests\n{\n    public class CartServiceTests\n    {\n        private readonly IHostBuilder _host;\n\n        public CartServiceTests()\n        {\n            _host = new HostBuilder().ConfigureWebHost(webBuilder =>\n            {\n                webBuilder\n                    .UseStartup<Startup>()\n                    .UseTestServer();\n            });\n        }\n\n        [Fact]\n        public async Task GetItem_NoAddItemBefore_EmptyCartReturned()\n        {\n            // Setup test server and client\n            using var server = await _host.StartAsync();\n            var httpClient = server.GetTestClient();\n\n            string userId = Guid.NewGuid().ToString();\n\n            // Create a GRPC communication channel between the client and the server\n            var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions\n            {\n                HttpClient = httpClient\n            });\n\n            var cartClient = new CartServiceClient(channel);\n\n            var request = new GetCartRequest\n            {\n                UserId = userId,\n            };\n\n            var cart = await cartClient.GetCartAsync(request);\n            Assert.NotNull(cart);\n\n            // All grpc objects implement IEquitable, so we can compare equality with by-value semantics\n            Assert.Equal(new Cart(), cart);\n        }\n\n        [Fact]\n        public async Task AddItem_ItemExists_Updated()\n        {\n            // Setup test server and client\n            using var server = await _host.StartAsync();\n            var httpClient = server.GetTestClient();\n\n            string userId = Guid.NewGuid().ToString();\n\n            // Create a GRPC communication channel between the client and the server\n            var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions\n            {\n                HttpClient = httpClient\n            });\n\n            var client = new CartServiceClient(channel);\n            var request = new AddItemRequest\n            {\n                UserId = userId,\n                Item = new CartItem\n                {\n                    ProductId = \"1\",\n                    Quantity = 1\n                }\n            };\n\n            // First add - nothing should fail\n            await client.AddItemAsync(request);\n\n            // Second add of existing product - quantity should be updated\n            await client.AddItemAsync(request);\n\n            var getCartRequest = new GetCartRequest\n            {\n                UserId = userId\n            };\n            var cart = await client.GetCartAsync(getCartRequest);\n            Assert.NotNull(cart);\n            Assert.Equal(userId, cart.UserId);\n            Assert.Single(cart.Items);\n            Assert.Equal(2, cart.Items[0].Quantity);\n\n            // Cleanup\n            await client.EmptyCartAsync(new EmptyCartRequest { UserId = userId });\n        }\n\n        [Fact]\n        public async Task AddItem_New_Inserted()\n        {\n            // Setup test server and client\n            using var server = await _host.StartAsync();\n            var httpClient = server.GetTestClient();\n\n            string userId = Guid.NewGuid().ToString();\n\n            // Create a GRPC communication channel between the client and the server\n            var channel = GrpcChannel.ForAddress(httpClient.BaseAddress, new GrpcChannelOptions\n            {\n                HttpClient = httpClient\n            });\n\n            // Create a proxy object to work with the server\n            var client = new CartServiceClient(channel);\n\n            var request = new AddItemRequest\n            {\n                UserId = userId,\n                Item = new CartItem\n                {\n                    ProductId = \"1\",\n                    Quantity = 1\n                }\n            };\n\n            await client.AddItemAsync(request);\n\n            var getCartRequest = new GetCartRequest\n            {\n                UserId = userId\n            };\n            var cart = await client.GetCartAsync(getCartRequest);\n            Assert.NotNull(cart);\n            Assert.Equal(userId, cart.UserId);\n            Assert.Single(cart.Items);\n\n            await client.EmptyCartAsync(new EmptyCartRequest { UserId = userId });\n            cart = await client.GetCartAsync(getCartRequest);\n            Assert.Empty(cart.Items);\n        }\n    }\n}\n"
  },
  {
    "path": "microservices-demo/src/cartservice/tests/cartservice.tests.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net6.0</TargetFramework>\n\n    <IsPackable>false</IsPackable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Grpc.Net.Client\" Version=\"2.48.0\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.TestHost\" Version=\"6.0.8\" />\n    <PackageReference Include=\"Microsoft.NET.Test.Sdk\" Version=\"17.3.0\" />\n    <PackageReference Include=\"xunit\" Version=\"2.4.2\" />\n    <PackageReference Include=\"xunit.runner.visualstudio\" Version=\"2.4.5\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\src\\cartservice.csproj\" />\n  </ItemGroup>\n</Project>\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/.dockerignore",
    "content": "vendor/\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM golang:1.18.4-alpine as builder\nRUN apk add --no-cache ca-certificates git\nRUN apk add build-base\nWORKDIR /src\n\n# restore dependencies\nCOPY go.mod go.sum ./\nRUN go mod download\n\nCOPY . .\n\n# Skaffold passes in debug-oriented compiler flags\nARG SKAFFOLD_GO_GCFLAGS\nRUN go build -gcflags=\"${SKAFFOLD_GO_GCFLAGS}\" -o /checkoutservice .\n\nFROM alpine as release\nRUN apk add --no-cache ca-certificates\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\nWORKDIR /src\nCOPY --from=builder /checkoutservice /src/checkoutservice\n\n# Definition of this variable is used by 'skaffold debug' to identify a golang binary.\n# Default behavior - a failure prints a stack trace for the current goroutine.\n# See https://golang.org/pkg/runtime/\nENV GOTRACEBACK=single\n\nEXPOSE 5050\nENTRYPOINT [\"/src/checkoutservice\"]\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/README.md",
    "content": "# checkoutservice\n\nRun the following command to restore dependencies to `vendor/` directory:\n\n    dep ensure --vendor-only\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/genproto/demo.pb.go",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: demo.proto\n\npackage hipstershop\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.com/golang/protobuf/proto\"\n\tmath \"math\"\n)\n\nimport (\n\tcontext \"golang.org/x/net/context\"\n\tgrpc \"google.golang.org/grpc\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype CartItem struct {\n\tProductId            string   `protobuf:\"bytes,1,opt,name=product_id,json=productId,proto3\" json:\"product_id,omitempty\"`\n\tQuantity             int32    `protobuf:\"varint,2,opt,name=quantity,proto3\" json:\"quantity,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CartItem) Reset()         { *m = CartItem{} }\nfunc (m *CartItem) String() string { return proto.CompactTextString(m) }\nfunc (*CartItem) ProtoMessage()    {}\nfunc (*CartItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{0}\n}\n\nfunc (m *CartItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CartItem.Unmarshal(m, b)\n}\nfunc (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CartItem.Marshal(b, m, deterministic)\n}\nfunc (m *CartItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CartItem.Merge(m, src)\n}\nfunc (m *CartItem) XXX_Size() int {\n\treturn xxx_messageInfo_CartItem.Size(m)\n}\nfunc (m *CartItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_CartItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CartItem proto.InternalMessageInfo\n\nfunc (m *CartItem) GetProductId() string {\n\tif m != nil {\n\t\treturn m.ProductId\n\t}\n\treturn \"\"\n}\n\nfunc (m *CartItem) GetQuantity() int32 {\n\tif m != nil {\n\t\treturn m.Quantity\n\t}\n\treturn 0\n}\n\ntype AddItemRequest struct {\n\tUserId               string    `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItem                 *CartItem `protobuf:\"bytes,2,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *AddItemRequest) Reset()         { *m = AddItemRequest{} }\nfunc (m *AddItemRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AddItemRequest) ProtoMessage()    {}\nfunc (*AddItemRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{1}\n}\n\nfunc (m *AddItemRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AddItemRequest.Unmarshal(m, b)\n}\nfunc (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AddItemRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AddItemRequest.Merge(m, src)\n}\nfunc (m *AddItemRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AddItemRequest.Size(m)\n}\nfunc (m *AddItemRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AddItemRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AddItemRequest proto.InternalMessageInfo\n\nfunc (m *AddItemRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *AddItemRequest) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\ntype EmptyCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *EmptyCartRequest) Reset()         { *m = EmptyCartRequest{} }\nfunc (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*EmptyCartRequest) ProtoMessage()    {}\nfunc (*EmptyCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{2}\n}\n\nfunc (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)\n}\nfunc (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *EmptyCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_EmptyCartRequest.Merge(m, src)\n}\nfunc (m *EmptyCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_EmptyCartRequest.Size(m)\n}\nfunc (m *EmptyCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_EmptyCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo\n\nfunc (m *EmptyCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype GetCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetCartRequest) Reset()         { *m = GetCartRequest{} }\nfunc (m *GetCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetCartRequest) ProtoMessage()    {}\nfunc (*GetCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{3}\n}\n\nfunc (m *GetCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetCartRequest.Unmarshal(m, b)\n}\nfunc (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetCartRequest.Merge(m, src)\n}\nfunc (m *GetCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetCartRequest.Size(m)\n}\nfunc (m *GetCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetCartRequest proto.InternalMessageInfo\n\nfunc (m *GetCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype Cart struct {\n\tUserId               string      `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *Cart) Reset()         { *m = Cart{} }\nfunc (m *Cart) String() string { return proto.CompactTextString(m) }\nfunc (*Cart) ProtoMessage()    {}\nfunc (*Cart) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{4}\n}\n\nfunc (m *Cart) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Cart.Unmarshal(m, b)\n}\nfunc (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Cart.Marshal(b, m, deterministic)\n}\nfunc (m *Cart) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Cart.Merge(m, src)\n}\nfunc (m *Cart) XXX_Size() int {\n\treturn xxx_messageInfo_Cart.Size(m)\n}\nfunc (m *Cart) XXX_DiscardUnknown() {\n\txxx_messageInfo_Cart.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Cart proto.InternalMessageInfo\n\nfunc (m *Cart) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *Cart) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype Empty struct {\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Empty) Reset()         { *m = Empty{} }\nfunc (m *Empty) String() string { return proto.CompactTextString(m) }\nfunc (*Empty) ProtoMessage()    {}\nfunc (*Empty) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{5}\n}\n\nfunc (m *Empty) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Empty.Unmarshal(m, b)\n}\nfunc (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Empty.Marshal(b, m, deterministic)\n}\nfunc (m *Empty) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Empty.Merge(m, src)\n}\nfunc (m *Empty) XXX_Size() int {\n\treturn xxx_messageInfo_Empty.Size(m)\n}\nfunc (m *Empty) XXX_DiscardUnknown() {\n\txxx_messageInfo_Empty.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Empty proto.InternalMessageInfo\n\ntype ListRecommendationsRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tProductIds           []string `protobuf:\"bytes,2,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsRequest) Reset()         { *m = ListRecommendationsRequest{} }\nfunc (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsRequest) ProtoMessage()    {}\nfunc (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{6}\n}\n\nfunc (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsRequest.Merge(m, src)\n}\nfunc (m *ListRecommendationsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Size(m)\n}\nfunc (m *ListRecommendationsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *ListRecommendationsRequest) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype ListRecommendationsResponse struct {\n\tProductIds           []string `protobuf:\"bytes,1,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsResponse) Reset()         { *m = ListRecommendationsResponse{} }\nfunc (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsResponse) ProtoMessage()    {}\nfunc (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{7}\n}\n\nfunc (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsResponse.Merge(m, src)\n}\nfunc (m *ListRecommendationsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Size(m)\n}\nfunc (m *ListRecommendationsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsResponse) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype Product struct {\n\tId          string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName        string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tPicture     string `protobuf:\"bytes,4,opt,name=picture,proto3\" json:\"picture,omitempty\"`\n\tPriceUsd    *Money `protobuf:\"bytes,5,opt,name=price_usd,json=priceUsd,proto3\" json:\"price_usd,omitempty\"`\n\t// Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n\t// other related products.\n\tCategories           []string `protobuf:\"bytes,6,rep,name=categories,proto3\" json:\"categories,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Product) Reset()         { *m = Product{} }\nfunc (m *Product) String() string { return proto.CompactTextString(m) }\nfunc (*Product) ProtoMessage()    {}\nfunc (*Product) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{8}\n}\n\nfunc (m *Product) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Product.Unmarshal(m, b)\n}\nfunc (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Product.Marshal(b, m, deterministic)\n}\nfunc (m *Product) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Product.Merge(m, src)\n}\nfunc (m *Product) XXX_Size() int {\n\treturn xxx_messageInfo_Product.Size(m)\n}\nfunc (m *Product) XXX_DiscardUnknown() {\n\txxx_messageInfo_Product.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Product proto.InternalMessageInfo\n\nfunc (m *Product) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetDescription() string {\n\tif m != nil {\n\t\treturn m.Description\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPicture() string {\n\tif m != nil {\n\t\treturn m.Picture\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPriceUsd() *Money {\n\tif m != nil {\n\t\treturn m.PriceUsd\n\t}\n\treturn nil\n}\n\nfunc (m *Product) GetCategories() []string {\n\tif m != nil {\n\t\treturn m.Categories\n\t}\n\treturn nil\n}\n\ntype ListProductsResponse struct {\n\tProducts             []*Product `protobuf:\"bytes,1,rep,name=products,proto3\" json:\"products,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *ListProductsResponse) Reset()         { *m = ListProductsResponse{} }\nfunc (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListProductsResponse) ProtoMessage()    {}\nfunc (*ListProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{9}\n}\n\nfunc (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)\n}\nfunc (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListProductsResponse.Merge(m, src)\n}\nfunc (m *ListProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListProductsResponse.Size(m)\n}\nfunc (m *ListProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo\n\nfunc (m *ListProductsResponse) GetProducts() []*Product {\n\tif m != nil {\n\t\treturn m.Products\n\t}\n\treturn nil\n}\n\ntype GetProductRequest struct {\n\tId                   string   `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetProductRequest) Reset()         { *m = GetProductRequest{} }\nfunc (m *GetProductRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetProductRequest) ProtoMessage()    {}\nfunc (*GetProductRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{10}\n}\n\nfunc (m *GetProductRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetProductRequest.Unmarshal(m, b)\n}\nfunc (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetProductRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetProductRequest.Merge(m, src)\n}\nfunc (m *GetProductRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetProductRequest.Size(m)\n}\nfunc (m *GetProductRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetProductRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetProductRequest proto.InternalMessageInfo\n\nfunc (m *GetProductRequest) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsRequest struct {\n\tQuery                string   `protobuf:\"bytes,1,opt,name=query,proto3\" json:\"query,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *SearchProductsRequest) Reset()         { *m = SearchProductsRequest{} }\nfunc (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsRequest) ProtoMessage()    {}\nfunc (*SearchProductsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{11}\n}\n\nfunc (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)\n}\nfunc (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsRequest.Merge(m, src)\n}\nfunc (m *SearchProductsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsRequest.Size(m)\n}\nfunc (m *SearchProductsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo\n\nfunc (m *SearchProductsRequest) GetQuery() string {\n\tif m != nil {\n\t\treturn m.Query\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsResponse struct {\n\tResults              []*Product `protobuf:\"bytes,1,rep,name=results,proto3\" json:\"results,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *SearchProductsResponse) Reset()         { *m = SearchProductsResponse{} }\nfunc (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsResponse) ProtoMessage()    {}\nfunc (*SearchProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{12}\n}\n\nfunc (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)\n}\nfunc (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsResponse.Merge(m, src)\n}\nfunc (m *SearchProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsResponse.Size(m)\n}\nfunc (m *SearchProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo\n\nfunc (m *SearchProductsResponse) GetResults() []*Product {\n\tif m != nil {\n\t\treturn m.Results\n\t}\n\treturn nil\n}\n\ntype GetQuoteRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *GetQuoteRequest) Reset()         { *m = GetQuoteRequest{} }\nfunc (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteRequest) ProtoMessage()    {}\nfunc (*GetQuoteRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{13}\n}\n\nfunc (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)\n}\nfunc (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteRequest.Merge(m, src)\n}\nfunc (m *GetQuoteRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteRequest.Size(m)\n}\nfunc (m *GetQuoteRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo\n\nfunc (m *GetQuoteRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *GetQuoteRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype GetQuoteResponse struct {\n\tCostUsd              *Money   `protobuf:\"bytes,1,opt,name=cost_usd,json=costUsd,proto3\" json:\"cost_usd,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetQuoteResponse) Reset()         { *m = GetQuoteResponse{} }\nfunc (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteResponse) ProtoMessage()    {}\nfunc (*GetQuoteResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{14}\n}\n\nfunc (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)\n}\nfunc (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteResponse.Merge(m, src)\n}\nfunc (m *GetQuoteResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteResponse.Size(m)\n}\nfunc (m *GetQuoteResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo\n\nfunc (m *GetQuoteResponse) GetCostUsd() *Money {\n\tif m != nil {\n\t\treturn m.CostUsd\n\t}\n\treturn nil\n}\n\ntype ShipOrderRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *ShipOrderRequest) Reset()         { *m = ShipOrderRequest{} }\nfunc (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderRequest) ProtoMessage()    {}\nfunc (*ShipOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{15}\n}\n\nfunc (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)\n}\nfunc (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderRequest.Merge(m, src)\n}\nfunc (m *ShipOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderRequest.Size(m)\n}\nfunc (m *ShipOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo\n\nfunc (m *ShipOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *ShipOrderRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype ShipOrderResponse struct {\n\tTrackingId           string   `protobuf:\"bytes,1,opt,name=tracking_id,json=trackingId,proto3\" json:\"tracking_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ShipOrderResponse) Reset()         { *m = ShipOrderResponse{} }\nfunc (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderResponse) ProtoMessage()    {}\nfunc (*ShipOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{16}\n}\n\nfunc (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)\n}\nfunc (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderResponse.Merge(m, src)\n}\nfunc (m *ShipOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderResponse.Size(m)\n}\nfunc (m *ShipOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo\n\nfunc (m *ShipOrderResponse) GetTrackingId() string {\n\tif m != nil {\n\t\treturn m.TrackingId\n\t}\n\treturn \"\"\n}\n\ntype Address struct {\n\tStreetAddress        string   `protobuf:\"bytes,1,opt,name=street_address,json=streetAddress,proto3\" json:\"street_address,omitempty\"`\n\tCity                 string   `protobuf:\"bytes,2,opt,name=city,proto3\" json:\"city,omitempty\"`\n\tState                string   `protobuf:\"bytes,3,opt,name=state,proto3\" json:\"state,omitempty\"`\n\tCountry              string   `protobuf:\"bytes,4,opt,name=country,proto3\" json:\"country,omitempty\"`\n\tZipCode              int32    `protobuf:\"varint,5,opt,name=zip_code,json=zipCode,proto3\" json:\"zip_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Address) Reset()         { *m = Address{} }\nfunc (m *Address) String() string { return proto.CompactTextString(m) }\nfunc (*Address) ProtoMessage()    {}\nfunc (*Address) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{17}\n}\n\nfunc (m *Address) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Address.Unmarshal(m, b)\n}\nfunc (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Address.Marshal(b, m, deterministic)\n}\nfunc (m *Address) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Address.Merge(m, src)\n}\nfunc (m *Address) XXX_Size() int {\n\treturn xxx_messageInfo_Address.Size(m)\n}\nfunc (m *Address) XXX_DiscardUnknown() {\n\txxx_messageInfo_Address.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Address proto.InternalMessageInfo\n\nfunc (m *Address) GetStreetAddress() string {\n\tif m != nil {\n\t\treturn m.StreetAddress\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCity() string {\n\tif m != nil {\n\t\treturn m.City\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetState() string {\n\tif m != nil {\n\t\treturn m.State\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCountry() string {\n\tif m != nil {\n\t\treturn m.Country\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetZipCode() int32 {\n\tif m != nil {\n\t\treturn m.ZipCode\n\t}\n\treturn 0\n}\n\n// Represents an amount of money with its currency type.\ntype Money struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCode string `protobuf:\"bytes,1,opt,name=currency_code,json=currencyCode,proto3\" json:\"currency_code,omitempty\"`\n\t// The whole units of the amount.\n\t// For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n\tUnits int64 `protobuf:\"varint,2,opt,name=units,proto3\" json:\"units,omitempty\"`\n\t// Number of nano (10^-9) units of the amount.\n\t// The value must be between -999,999,999 and +999,999,999 inclusive.\n\t// If `units` is positive, `nanos` must be positive or zero.\n\t// If `units` is zero, `nanos` can be positive, zero, or negative.\n\t// If `units` is negative, `nanos` must be negative or zero.\n\t// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n\tNanos                int32    `protobuf:\"varint,3,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Money) Reset()         { *m = Money{} }\nfunc (m *Money) String() string { return proto.CompactTextString(m) }\nfunc (*Money) ProtoMessage()    {}\nfunc (*Money) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{18}\n}\n\nfunc (m *Money) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Money.Unmarshal(m, b)\n}\nfunc (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Money.Marshal(b, m, deterministic)\n}\nfunc (m *Money) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Money.Merge(m, src)\n}\nfunc (m *Money) XXX_Size() int {\n\treturn xxx_messageInfo_Money.Size(m)\n}\nfunc (m *Money) XXX_DiscardUnknown() {\n\txxx_messageInfo_Money.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Money proto.InternalMessageInfo\n\nfunc (m *Money) GetCurrencyCode() string {\n\tif m != nil {\n\t\treturn m.CurrencyCode\n\t}\n\treturn \"\"\n}\n\nfunc (m *Money) GetUnits() int64 {\n\tif m != nil {\n\t\treturn m.Units\n\t}\n\treturn 0\n}\n\nfunc (m *Money) GetNanos() int32 {\n\tif m != nil {\n\t\treturn m.Nanos\n\t}\n\treturn 0\n}\n\ntype GetSupportedCurrenciesResponse struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCodes        []string `protobuf:\"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3\" json:\"currency_codes,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetSupportedCurrenciesResponse) Reset()         { *m = GetSupportedCurrenciesResponse{} }\nfunc (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetSupportedCurrenciesResponse) ProtoMessage()    {}\nfunc (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{19}\n}\n\nfunc (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo\n\nfunc (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string {\n\tif m != nil {\n\t\treturn m.CurrencyCodes\n\t}\n\treturn nil\n}\n\ntype CurrencyConversionRequest struct {\n\tFrom *Money `protobuf:\"bytes,1,opt,name=from,proto3\" json:\"from,omitempty\"`\n\t// The 3-letter currency code defined in ISO 4217.\n\tToCode               string   `protobuf:\"bytes,2,opt,name=to_code,json=toCode,proto3\" json:\"to_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CurrencyConversionRequest) Reset()         { *m = CurrencyConversionRequest{} }\nfunc (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }\nfunc (*CurrencyConversionRequest) ProtoMessage()    {}\nfunc (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{20}\n}\n\nfunc (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)\n}\nfunc (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)\n}\nfunc (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CurrencyConversionRequest.Merge(m, src)\n}\nfunc (m *CurrencyConversionRequest) XXX_Size() int {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Size(m)\n}\nfunc (m *CurrencyConversionRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo\n\nfunc (m *CurrencyConversionRequest) GetFrom() *Money {\n\tif m != nil {\n\t\treturn m.From\n\t}\n\treturn nil\n}\n\nfunc (m *CurrencyConversionRequest) GetToCode() string {\n\tif m != nil {\n\t\treturn m.ToCode\n\t}\n\treturn \"\"\n}\n\ntype CreditCardInfo struct {\n\tCreditCardNumber          string   `protobuf:\"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3\" json:\"credit_card_number,omitempty\"`\n\tCreditCardCvv             int32    `protobuf:\"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3\" json:\"credit_card_cvv,omitempty\"`\n\tCreditCardExpirationYear  int32    `protobuf:\"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3\" json:\"credit_card_expiration_year,omitempty\"`\n\tCreditCardExpirationMonth int32    `protobuf:\"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3\" json:\"credit_card_expiration_month,omitempty\"`\n\tXXX_NoUnkeyedLiteral      struct{} `json:\"-\"`\n\tXXX_unrecognized          []byte   `json:\"-\"`\n\tXXX_sizecache             int32    `json:\"-\"`\n}\n\nfunc (m *CreditCardInfo) Reset()         { *m = CreditCardInfo{} }\nfunc (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }\nfunc (*CreditCardInfo) ProtoMessage()    {}\nfunc (*CreditCardInfo) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{21}\n}\n\nfunc (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)\n}\nfunc (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)\n}\nfunc (m *CreditCardInfo) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CreditCardInfo.Merge(m, src)\n}\nfunc (m *CreditCardInfo) XXX_Size() int {\n\treturn xxx_messageInfo_CreditCardInfo.Size(m)\n}\nfunc (m *CreditCardInfo) XXX_DiscardUnknown() {\n\txxx_messageInfo_CreditCardInfo.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo\n\nfunc (m *CreditCardInfo) GetCreditCardNumber() string {\n\tif m != nil {\n\t\treturn m.CreditCardNumber\n\t}\n\treturn \"\"\n}\n\nfunc (m *CreditCardInfo) GetCreditCardCvv() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardCvv\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationYear() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationYear\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationMonth\n\t}\n\treturn 0\n}\n\ntype ChargeRequest struct {\n\tAmount               *Money          `protobuf:\"bytes,1,opt,name=amount,proto3\" json:\"amount,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,2,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *ChargeRequest) Reset()         { *m = ChargeRequest{} }\nfunc (m *ChargeRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeRequest) ProtoMessage()    {}\nfunc (*ChargeRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{22}\n}\n\nfunc (m *ChargeRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeRequest.Unmarshal(m, b)\n}\nfunc (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeRequest.Merge(m, src)\n}\nfunc (m *ChargeRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeRequest.Size(m)\n}\nfunc (m *ChargeRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeRequest proto.InternalMessageInfo\n\nfunc (m *ChargeRequest) GetAmount() *Money {\n\tif m != nil {\n\t\treturn m.Amount\n\t}\n\treturn nil\n}\n\nfunc (m *ChargeRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype ChargeResponse struct {\n\tTransactionId        string   `protobuf:\"bytes,1,opt,name=transaction_id,json=transactionId,proto3\" json:\"transaction_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ChargeResponse) Reset()         { *m = ChargeResponse{} }\nfunc (m *ChargeResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeResponse) ProtoMessage()    {}\nfunc (*ChargeResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{23}\n}\n\nfunc (m *ChargeResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeResponse.Unmarshal(m, b)\n}\nfunc (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeResponse.Merge(m, src)\n}\nfunc (m *ChargeResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeResponse.Size(m)\n}\nfunc (m *ChargeResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeResponse proto.InternalMessageInfo\n\nfunc (m *ChargeResponse) GetTransactionId() string {\n\tif m != nil {\n\t\treturn m.TransactionId\n\t}\n\treturn \"\"\n}\n\ntype OrderItem struct {\n\tItem                 *CartItem `protobuf:\"bytes,1,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tCost                 *Money    `protobuf:\"bytes,2,opt,name=cost,proto3\" json:\"cost,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *OrderItem) Reset()         { *m = OrderItem{} }\nfunc (m *OrderItem) String() string { return proto.CompactTextString(m) }\nfunc (*OrderItem) ProtoMessage()    {}\nfunc (*OrderItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{24}\n}\n\nfunc (m *OrderItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderItem.Unmarshal(m, b)\n}\nfunc (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)\n}\nfunc (m *OrderItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderItem.Merge(m, src)\n}\nfunc (m *OrderItem) XXX_Size() int {\n\treturn xxx_messageInfo_OrderItem.Size(m)\n}\nfunc (m *OrderItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderItem proto.InternalMessageInfo\n\nfunc (m *OrderItem) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\nfunc (m *OrderItem) GetCost() *Money {\n\tif m != nil {\n\t\treturn m.Cost\n\t}\n\treturn nil\n}\n\ntype OrderResult struct {\n\tOrderId              string       `protobuf:\"bytes,1,opt,name=order_id,json=orderId,proto3\" json:\"order_id,omitempty\"`\n\tShippingTrackingId   string       `protobuf:\"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3\" json:\"shipping_tracking_id,omitempty\"`\n\tShippingCost         *Money       `protobuf:\"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3\" json:\"shipping_cost,omitempty\"`\n\tShippingAddress      *Address     `protobuf:\"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3\" json:\"shipping_address,omitempty\"`\n\tItems                []*OrderItem `protobuf:\"bytes,5,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *OrderResult) Reset()         { *m = OrderResult{} }\nfunc (m *OrderResult) String() string { return proto.CompactTextString(m) }\nfunc (*OrderResult) ProtoMessage()    {}\nfunc (*OrderResult) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{25}\n}\n\nfunc (m *OrderResult) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderResult.Unmarshal(m, b)\n}\nfunc (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)\n}\nfunc (m *OrderResult) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderResult.Merge(m, src)\n}\nfunc (m *OrderResult) XXX_Size() int {\n\treturn xxx_messageInfo_OrderResult.Size(m)\n}\nfunc (m *OrderResult) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderResult.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderResult proto.InternalMessageInfo\n\nfunc (m *OrderResult) GetOrderId() string {\n\tif m != nil {\n\t\treturn m.OrderId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingTrackingId() string {\n\tif m != nil {\n\t\treturn m.ShippingTrackingId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingCost() *Money {\n\tif m != nil {\n\t\treturn m.ShippingCost\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetShippingAddress() *Address {\n\tif m != nil {\n\t\treturn m.ShippingAddress\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetItems() []*OrderItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype SendOrderConfirmationRequest struct {\n\tEmail                string       `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tOrder                *OrderResult `protobuf:\"bytes,2,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *SendOrderConfirmationRequest) Reset()         { *m = SendOrderConfirmationRequest{} }\nfunc (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SendOrderConfirmationRequest) ProtoMessage()    {}\nfunc (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{26}\n}\n\nfunc (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Size(m)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo\n\nfunc (m *SendOrderConfirmationRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *SendOrderConfirmationRequest) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype PlaceOrderRequest struct {\n\tUserId               string          `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tUserCurrency         string          `protobuf:\"bytes,2,opt,name=user_currency,json=userCurrency,proto3\" json:\"user_currency,omitempty\"`\n\tAddress              *Address        `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tEmail                string          `protobuf:\"bytes,5,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,6,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *PlaceOrderRequest) Reset()         { *m = PlaceOrderRequest{} }\nfunc (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderRequest) ProtoMessage()    {}\nfunc (*PlaceOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{27}\n}\n\nfunc (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderRequest.Merge(m, src)\n}\nfunc (m *PlaceOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderRequest.Size(m)\n}\nfunc (m *PlaceOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo\n\nfunc (m *PlaceOrderRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetUserCurrency() string {\n\tif m != nil {\n\t\treturn m.UserCurrency\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *PlaceOrderRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype PlaceOrderResponse struct {\n\tOrder                *OrderResult `protobuf:\"bytes,1,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *PlaceOrderResponse) Reset()         { *m = PlaceOrderResponse{} }\nfunc (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderResponse) ProtoMessage()    {}\nfunc (*PlaceOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{28}\n}\n\nfunc (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderResponse.Merge(m, src)\n}\nfunc (m *PlaceOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderResponse.Size(m)\n}\nfunc (m *PlaceOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo\n\nfunc (m *PlaceOrderResponse) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype AdRequest struct {\n\t// List of important key words from the current page describing the context.\n\tContextKeys          []string `protobuf:\"bytes,1,rep,name=context_keys,json=contextKeys,proto3\" json:\"context_keys,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdRequest) Reset()         { *m = AdRequest{} }\nfunc (m *AdRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AdRequest) ProtoMessage()    {}\nfunc (*AdRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{29}\n}\n\nfunc (m *AdRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdRequest.Unmarshal(m, b)\n}\nfunc (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AdRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdRequest.Merge(m, src)\n}\nfunc (m *AdRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AdRequest.Size(m)\n}\nfunc (m *AdRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdRequest proto.InternalMessageInfo\n\nfunc (m *AdRequest) GetContextKeys() []string {\n\tif m != nil {\n\t\treturn m.ContextKeys\n\t}\n\treturn nil\n}\n\ntype AdResponse struct {\n\tAds                  []*Ad    `protobuf:\"bytes,1,rep,name=ads,proto3\" json:\"ads,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdResponse) Reset()         { *m = AdResponse{} }\nfunc (m *AdResponse) String() string { return proto.CompactTextString(m) }\nfunc (*AdResponse) ProtoMessage()    {}\nfunc (*AdResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{30}\n}\n\nfunc (m *AdResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdResponse.Unmarshal(m, b)\n}\nfunc (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)\n}\nfunc (m *AdResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdResponse.Merge(m, src)\n}\nfunc (m *AdResponse) XXX_Size() int {\n\treturn xxx_messageInfo_AdResponse.Size(m)\n}\nfunc (m *AdResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdResponse proto.InternalMessageInfo\n\nfunc (m *AdResponse) GetAds() []*Ad {\n\tif m != nil {\n\t\treturn m.Ads\n\t}\n\treturn nil\n}\n\ntype Ad struct {\n\t// url to redirect to when an ad is clicked.\n\tRedirectUrl string `protobuf:\"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3\" json:\"redirect_url,omitempty\"`\n\t// short advertisement text to display.\n\tText                 string   `protobuf:\"bytes,2,opt,name=text,proto3\" json:\"text,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Ad) Reset()         { *m = Ad{} }\nfunc (m *Ad) String() string { return proto.CompactTextString(m) }\nfunc (*Ad) ProtoMessage()    {}\nfunc (*Ad) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{31}\n}\n\nfunc (m *Ad) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Ad.Unmarshal(m, b)\n}\nfunc (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Ad.Marshal(b, m, deterministic)\n}\nfunc (m *Ad) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Ad.Merge(m, src)\n}\nfunc (m *Ad) XXX_Size() int {\n\treturn xxx_messageInfo_Ad.Size(m)\n}\nfunc (m *Ad) XXX_DiscardUnknown() {\n\txxx_messageInfo_Ad.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Ad proto.InternalMessageInfo\n\nfunc (m *Ad) GetRedirectUrl() string {\n\tif m != nil {\n\t\treturn m.RedirectUrl\n\t}\n\treturn \"\"\n}\n\nfunc (m *Ad) GetText() string {\n\tif m != nil {\n\t\treturn m.Text\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*CartItem)(nil), \"hipstershop.CartItem\")\n\tproto.RegisterType((*AddItemRequest)(nil), \"hipstershop.AddItemRequest\")\n\tproto.RegisterType((*EmptyCartRequest)(nil), \"hipstershop.EmptyCartRequest\")\n\tproto.RegisterType((*GetCartRequest)(nil), \"hipstershop.GetCartRequest\")\n\tproto.RegisterType((*Cart)(nil), \"hipstershop.Cart\")\n\tproto.RegisterType((*Empty)(nil), \"hipstershop.Empty\")\n\tproto.RegisterType((*ListRecommendationsRequest)(nil), \"hipstershop.ListRecommendationsRequest\")\n\tproto.RegisterType((*ListRecommendationsResponse)(nil), \"hipstershop.ListRecommendationsResponse\")\n\tproto.RegisterType((*Product)(nil), \"hipstershop.Product\")\n\tproto.RegisterType((*ListProductsResponse)(nil), \"hipstershop.ListProductsResponse\")\n\tproto.RegisterType((*GetProductRequest)(nil), \"hipstershop.GetProductRequest\")\n\tproto.RegisterType((*SearchProductsRequest)(nil), \"hipstershop.SearchProductsRequest\")\n\tproto.RegisterType((*SearchProductsResponse)(nil), \"hipstershop.SearchProductsResponse\")\n\tproto.RegisterType((*GetQuoteRequest)(nil), \"hipstershop.GetQuoteRequest\")\n\tproto.RegisterType((*GetQuoteResponse)(nil), \"hipstershop.GetQuoteResponse\")\n\tproto.RegisterType((*ShipOrderRequest)(nil), \"hipstershop.ShipOrderRequest\")\n\tproto.RegisterType((*ShipOrderResponse)(nil), \"hipstershop.ShipOrderResponse\")\n\tproto.RegisterType((*Address)(nil), \"hipstershop.Address\")\n\tproto.RegisterType((*Money)(nil), \"hipstershop.Money\")\n\tproto.RegisterType((*GetSupportedCurrenciesResponse)(nil), \"hipstershop.GetSupportedCurrenciesResponse\")\n\tproto.RegisterType((*CurrencyConversionRequest)(nil), \"hipstershop.CurrencyConversionRequest\")\n\tproto.RegisterType((*CreditCardInfo)(nil), \"hipstershop.CreditCardInfo\")\n\tproto.RegisterType((*ChargeRequest)(nil), \"hipstershop.ChargeRequest\")\n\tproto.RegisterType((*ChargeResponse)(nil), \"hipstershop.ChargeResponse\")\n\tproto.RegisterType((*OrderItem)(nil), \"hipstershop.OrderItem\")\n\tproto.RegisterType((*OrderResult)(nil), \"hipstershop.OrderResult\")\n\tproto.RegisterType((*SendOrderConfirmationRequest)(nil), \"hipstershop.SendOrderConfirmationRequest\")\n\tproto.RegisterType((*PlaceOrderRequest)(nil), \"hipstershop.PlaceOrderRequest\")\n\tproto.RegisterType((*PlaceOrderResponse)(nil), \"hipstershop.PlaceOrderResponse\")\n\tproto.RegisterType((*AdRequest)(nil), \"hipstershop.AdRequest\")\n\tproto.RegisterType((*AdResponse)(nil), \"hipstershop.AdResponse\")\n\tproto.RegisterType((*Ad)(nil), \"hipstershop.Ad\")\n}\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ context.Context\nvar _ grpc.ClientConn\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\nconst _ = grpc.SupportPackageIsVersion4\n\n// CartServiceClient is the client API for CartService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CartServiceClient interface {\n\tAddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error)\n\tGetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error)\n\tEmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype cartServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient {\n\treturn &cartServiceClient{cc}\n}\n\nfunc (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/AddItem\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) {\n\tout := new(Cart)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/GetCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/EmptyCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CartServiceServer is the server API for CartService service.\ntype CartServiceServer interface {\n\tAddItem(context.Context, *AddItemRequest) (*Empty, error)\n\tGetCart(context.Context, *GetCartRequest) (*Cart, error)\n\tEmptyCart(context.Context, *EmptyCartRequest) (*Empty, error)\n}\n\nfunc RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) {\n\ts.RegisterService(&_CartService_serviceDesc, srv)\n}\n\nfunc _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddItemRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/AddItem\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/GetCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(EmptyCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/EmptyCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CartService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CartService\",\n\tHandlerType: (*CartServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"AddItem\",\n\t\t\tHandler:    _CartService_AddItem_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetCart\",\n\t\t\tHandler:    _CartService_GetCart_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"EmptyCart\",\n\t\t\tHandler:    _CartService_EmptyCart_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// RecommendationServiceClient is the client API for RecommendationService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype RecommendationServiceClient interface {\n\tListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error)\n}\n\ntype recommendationServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {\n\treturn &recommendationServiceClient{cc}\n}\n\nfunc (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) {\n\tout := new(ListRecommendationsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.RecommendationService/ListRecommendations\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// RecommendationServiceServer is the server API for RecommendationService service.\ntype RecommendationServiceServer interface {\n\tListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error)\n}\n\nfunc RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {\n\ts.RegisterService(&_RecommendationService_serviceDesc, srv)\n}\n\nfunc _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListRecommendationsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.RecommendationService/ListRecommendations\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _RecommendationService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.RecommendationService\",\n\tHandlerType: (*RecommendationServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListRecommendations\",\n\t\t\tHandler:    _RecommendationService_ListRecommendations_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ProductCatalogServiceClient is the client API for ProductCatalogService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ProductCatalogServiceClient interface {\n\tListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error)\n\tGetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error)\n\tSearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error)\n}\n\ntype productCatalogServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient {\n\treturn &productCatalogServiceClient{cc}\n}\n\nfunc (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) {\n\tout := new(ListProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/ListProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) {\n\tout := new(Product)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/GetProduct\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) {\n\tout := new(SearchProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/SearchProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ProductCatalogServiceServer is the server API for ProductCatalogService service.\ntype ProductCatalogServiceServer interface {\n\tListProducts(context.Context, *Empty) (*ListProductsResponse, error)\n\tGetProduct(context.Context, *GetProductRequest) (*Product, error)\n\tSearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error)\n}\n\nfunc RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) {\n\ts.RegisterService(&_ProductCatalogService_serviceDesc, srv)\n}\n\nfunc _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/ListProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetProductRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/GetProduct\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SearchProductsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/SearchProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ProductCatalogService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ProductCatalogService\",\n\tHandlerType: (*ProductCatalogServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListProducts\",\n\t\t\tHandler:    _ProductCatalogService_ListProducts_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetProduct\",\n\t\t\tHandler:    _ProductCatalogService_GetProduct_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"SearchProducts\",\n\t\t\tHandler:    _ProductCatalogService_SearchProducts_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ShippingServiceClient is the client API for ShippingService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ShippingServiceClient interface {\n\tGetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error)\n\tShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error)\n}\n\ntype shippingServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient {\n\treturn &shippingServiceClient{cc}\n}\n\nfunc (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) {\n\tout := new(GetQuoteResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/GetQuote\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) {\n\tout := new(ShipOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/ShipOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ShippingServiceServer is the server API for ShippingService service.\ntype ShippingServiceServer interface {\n\tGetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error)\n\tShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error)\n}\n\nfunc RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) {\n\ts.RegisterService(&_ShippingService_serviceDesc, srv)\n}\n\nfunc _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetQuoteRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/GetQuote\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ShipOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/ShipOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ShippingService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ShippingService\",\n\tHandlerType: (*ShippingServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetQuote\",\n\t\t\tHandler:    _ShippingService_GetQuote_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"ShipOrder\",\n\t\t\tHandler:    _ShippingService_ShipOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CurrencyServiceClient is the client API for CurrencyService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CurrencyServiceClient interface {\n\tGetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error)\n\tConvert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error)\n}\n\ntype currencyServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient {\n\treturn &currencyServiceClient{cc}\n}\n\nfunc (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) {\n\tout := new(GetSupportedCurrenciesResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/GetSupportedCurrencies\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) {\n\tout := new(Money)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/Convert\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CurrencyServiceServer is the server API for CurrencyService service.\ntype CurrencyServiceServer interface {\n\tGetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error)\n\tConvert(context.Context, *CurrencyConversionRequest) (*Money, error)\n}\n\nfunc RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) {\n\ts.RegisterService(&_CurrencyService_serviceDesc, srv)\n}\n\nfunc _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/GetSupportedCurrencies\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(CurrencyConversionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/Convert\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CurrencyService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CurrencyService\",\n\tHandlerType: (*CurrencyServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetSupportedCurrencies\",\n\t\t\tHandler:    _CurrencyService_GetSupportedCurrencies_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"Convert\",\n\t\t\tHandler:    _CurrencyService_Convert_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// PaymentServiceClient is the client API for PaymentService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype PaymentServiceClient interface {\n\tCharge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error)\n}\n\ntype paymentServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient {\n\treturn &paymentServiceClient{cc}\n}\n\nfunc (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) {\n\tout := new(ChargeResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.PaymentService/Charge\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// PaymentServiceServer is the server API for PaymentService service.\ntype PaymentServiceServer interface {\n\tCharge(context.Context, *ChargeRequest) (*ChargeResponse, error)\n}\n\nfunc RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) {\n\ts.RegisterService(&_PaymentService_serviceDesc, srv)\n}\n\nfunc _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ChargeRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.PaymentService/Charge\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _PaymentService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.PaymentService\",\n\tHandlerType: (*PaymentServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Charge\",\n\t\t\tHandler:    _PaymentService_Charge_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// EmailServiceClient is the client API for EmailService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype EmailServiceClient interface {\n\tSendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype emailServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient {\n\treturn &emailServiceClient{cc}\n}\n\nfunc (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.EmailService/SendOrderConfirmation\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// EmailServiceServer is the server API for EmailService service.\ntype EmailServiceServer interface {\n\tSendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error)\n}\n\nfunc RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) {\n\ts.RegisterService(&_EmailService_serviceDesc, srv)\n}\n\nfunc _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SendOrderConfirmationRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.EmailService/SendOrderConfirmation\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _EmailService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.EmailService\",\n\tHandlerType: (*EmailServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"SendOrderConfirmation\",\n\t\t\tHandler:    _EmailService_SendOrderConfirmation_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CheckoutServiceClient is the client API for CheckoutService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CheckoutServiceClient interface {\n\tPlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error)\n}\n\ntype checkoutServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient {\n\treturn &checkoutServiceClient{cc}\n}\n\nfunc (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) {\n\tout := new(PlaceOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CheckoutService/PlaceOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CheckoutServiceServer is the server API for CheckoutService service.\ntype CheckoutServiceServer interface {\n\tPlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error)\n}\n\nfunc RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) {\n\ts.RegisterService(&_CheckoutService_serviceDesc, srv)\n}\n\nfunc _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PlaceOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CheckoutService/PlaceOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CheckoutService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CheckoutService\",\n\tHandlerType: (*CheckoutServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"PlaceOrder\",\n\t\t\tHandler:    _CheckoutService_PlaceOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// AdServiceClient is the client API for AdService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype AdServiceClient interface {\n\tGetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error)\n}\n\ntype adServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient {\n\treturn &adServiceClient{cc}\n}\n\nfunc (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) {\n\tout := new(AdResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.AdService/GetAds\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// AdServiceServer is the server API for AdService service.\ntype AdServiceServer interface {\n\tGetAds(context.Context, *AdRequest) (*AdResponse, error)\n}\n\nfunc RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) {\n\ts.RegisterService(&_AdService_serviceDesc, srv)\n}\n\nfunc _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AdRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.AdService/GetAds\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _AdService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.AdService\",\n\tHandlerType: (*AdServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetAds\",\n\t\t\tHandler:    _AdService_GetAds_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\nfunc init() { proto.RegisterFile(\"demo.proto\", fileDescriptor_ca53982754088a9d) }\n\nvar fileDescriptor_ca53982754088a9d = []byte{\n\t// 1500 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7,\n\t0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81,\n\t0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0,\n\t0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc,\n\t0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8,\n\t0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8,\n\t0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29,\n\t0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88,\n\t0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20,\n\t0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93,\n\t0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0,\n\t0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad,\n\t0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e,\n\t0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85,\n\t0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32,\n\t0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20,\n\t0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2,\n\t0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7,\n\t0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d,\n\t0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8,\n\t0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93,\n\t0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b,\n\t0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28,\n\t0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04,\n\t0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72,\n\t0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99,\n\t0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab,\n\t0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7,\n\t0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26,\n\t0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f,\n\t0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0,\n\t0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07,\n\t0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe,\n\t0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34,\n\t0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52,\n\t0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3,\n\t0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11,\n\t0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63,\n\t0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13,\n\t0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49,\n\t0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a,\n\t0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29,\n\t0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca,\n\t0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55,\n\t0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71,\n\t0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97,\n\t0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d,\n\t0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff,\n\t0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb,\n\t0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1,\n\t0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8,\n\t0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4,\n\t0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0,\n\t0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69,\n\t0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb,\n\t0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d,\n\t0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7,\n\t0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99,\n\t0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98,\n\t0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9,\n\t0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02,\n\t0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d,\n\t0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d,\n\t0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa,\n\t0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9,\n\t0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7,\n\t0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce,\n\t0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47,\n\t0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d,\n\t0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23,\n\t0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac,\n\t0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca,\n\t0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb,\n\t0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99,\n\t0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe,\n\t0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff,\n\t0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07,\n\t0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87,\n\t0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8,\n\t0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33,\n\t0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93,\n\t0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2,\n\t0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43,\n\t0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6,\n\t0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31,\n\t0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21,\n\t0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc,\n\t0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43,\n\t0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd,\n\t0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2,\n\t0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f,\n\t0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a,\n\t0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b,\n\t0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00,\n}\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_checkoutservice_genproto]\n\nPATH=$PATH:$GOPATH/bin\nprotodir=../../pb\n\nprotoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto\n\n# [END gke_checkoutservice_genproto]"
  },
  {
    "path": "microservices-demo/src/checkoutservice/go.mod",
    "content": "module github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice\n\ngo 1.18\n\nrequire (\n\tcloud.google.com/go/profiler v0.3.0\n\tcontrib.go.opencensus.io/exporter/jaeger v0.2.1\n\tcontrib.go.opencensus.io/exporter/stackdriver v0.13.12\n\tgithub.com/golang/protobuf v1.5.2\n\tgithub.com/google/uuid v1.3.0\n\tgithub.com/sirupsen/logrus v1.8.1\n\tgo.opencensus.io v0.23.0\n\tgolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b\n\tgoogle.golang.org/grpc v1.48.0\n)\n\nrequire (\n\tcloud.google.com/go v0.100.2 // indirect\n\tcloud.google.com/go/compute v1.6.1 // indirect\n\tcloud.google.com/go/monitoring v1.1.0 // indirect\n\tcloud.google.com/go/trace v1.0.0 // indirect\n\tgithub.com/aws/aws-sdk-go v1.43.31 // indirect\n\tgithub.com/census-instrumentation/opencensus-proto v0.3.0 // indirect\n\tgithub.com/cespare/xxhash v1.1.0 // indirect\n\tgithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect\n\tgithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/google/go-cmp v0.5.8 // indirect\n\tgithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.4.0 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/prometheus/prometheus v2.5.0+incompatible // indirect\n\tgithub.com/uber/jaeger-client-go v2.25.0+incompatible // indirect\n\tgolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect\n\tgolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgoogle.golang.org/api v0.78.0 // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect\n\tgoogle.golang.org/protobuf v1.28.0 // indirect\n)\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo=\ncloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=\ncloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ=\ncloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4=\ncloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo=\ncloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=\ncloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=\ngithub.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=\ngithub.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0=\ngithub.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=\ngithub.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=\ngithub.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/main.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"time\"\n\n\t\"cloud.google.com/go/profiler\"\n\t\"contrib.go.opencensus.io/exporter/jaeger\"\n\t\"contrib.go.opencensus.io/exporter/stackdriver\"\n\t\"github.com/google/uuid\"\n\t\"github.com/sirupsen/logrus\"\n\t\"go.opencensus.io/plugin/ocgrpc\"\n\t\"go.opencensus.io/stats/view\"\n\t\"go.opencensus.io/trace\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto\"\n\tmoney \"github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/money\"\n\thealthpb \"google.golang.org/grpc/health/grpc_health_v1\"\n)\n\nconst (\n\tlistenPort  = \"5050\"\n\tusdCurrency = \"USD\"\n)\n\nvar log *logrus.Logger\n\nfunc init() {\n\tlog = logrus.New()\n\tlog.Level = logrus.DebugLevel\n\tlog.Formatter = &logrus.JSONFormatter{\n\t\tFieldMap: logrus.FieldMap{\n\t\t\tlogrus.FieldKeyTime:  \"timestamp\",\n\t\t\tlogrus.FieldKeyLevel: \"severity\",\n\t\t\tlogrus.FieldKeyMsg:   \"message\",\n\t\t},\n\t\tTimestampFormat: time.RFC3339Nano,\n\t}\n\tlog.Out = os.Stdout\n}\n\ntype checkoutService struct {\n\tproductCatalogSvcAddr string\n\tcartSvcAddr           string\n\tcurrencySvcAddr       string\n\tshippingSvcAddr       string\n\temailSvcAddr          string\n\tpaymentSvcAddr        string\n}\n\nfunc main() {\n\tif os.Getenv(\"DISABLE_TRACING\") == \"\" {\n\t\tlog.Info(\"Tracing enabled.\")\n\t\tgo initTracing()\n\t} else {\n\t\tlog.Info(\"Tracing disabled.\")\n\t}\n\n\tif os.Getenv(\"DISABLE_PROFILER\") == \"\" {\n\t\tlog.Info(\"Profiling enabled.\")\n\t\tgo initProfiling(\"checkoutservice\", \"1.0.0\")\n\t} else {\n\t\tlog.Info(\"Profiling disabled.\")\n\t}\n\n\tport := listenPort\n\tif os.Getenv(\"PORT\") != \"\" {\n\t\tport = os.Getenv(\"PORT\")\n\t}\n\n\tsvc := new(checkoutService)\n\tmustMapEnv(&svc.shippingSvcAddr, \"SHIPPING_SERVICE_ADDR\")\n\tmustMapEnv(&svc.productCatalogSvcAddr, \"PRODUCT_CATALOG_SERVICE_ADDR\")\n\tmustMapEnv(&svc.cartSvcAddr, \"CART_SERVICE_ADDR\")\n\tmustMapEnv(&svc.currencySvcAddr, \"CURRENCY_SERVICE_ADDR\")\n\tmustMapEnv(&svc.emailSvcAddr, \"EMAIL_SERVICE_ADDR\")\n\tmustMapEnv(&svc.paymentSvcAddr, \"PAYMENT_SERVICE_ADDR\")\n\n\tlog.Infof(\"service config: %+v\", svc)\n\n\tlis, err := net.Listen(\"tcp\", fmt.Sprintf(\":%s\", port))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tvar srv *grpc.Server\n\tif os.Getenv(\"DISABLE_STATS\") == \"\" {\n\t\tlog.Info(\"Stats enabled.\")\n\t\tsrv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))\n\t} else {\n\t\tlog.Info(\"Stats disabled.\")\n\t\tsrv = grpc.NewServer()\n\t}\n\tpb.RegisterCheckoutServiceServer(srv, svc)\n\thealthpb.RegisterHealthServer(srv, svc)\n\tlog.Infof(\"starting to listen on tcp: %q\", lis.Addr().String())\n\terr = srv.Serve(lis)\n\tlog.Fatal(err)\n}\n\nfunc initJaegerTracing() {\n\tsvcAddr := os.Getenv(\"JAEGER_SERVICE_ADDR\")\n\tif svcAddr == \"\" {\n\t\tlog.Info(\"jaeger initialization disabled.\")\n\t\treturn\n\t}\n\n\t// Register the Jaeger exporter to be able to retrieve\n\t// the collected spans.\n\texporter, err := jaeger.NewExporter(jaeger.Options{\n\t\tEndpoint: fmt.Sprintf(\"http://%s\", svcAddr),\n\t\tProcess: jaeger.Process{\n\t\t\tServiceName: \"checkoutservice\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\ttrace.RegisterExporter(exporter)\n\tlog.Info(\"jaeger initialization completed.\")\n}\n\nfunc initStats(exporter *stackdriver.Exporter) {\n\tview.SetReportingPeriod(60 * time.Second)\n\tview.RegisterExporter(exporter)\n\tif err := view.Register(ocgrpc.DefaultServerViews...); err != nil {\n\t\tlog.Warn(\"Error registering default server views\")\n\t} else {\n\t\tlog.Info(\"Registered default server views\")\n\t}\n}\n\nfunc initStackdriverTracing() {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\texporter, err := stackdriver.NewExporter(stackdriver.Options{})\n\t\tif err != nil {\n\t\t\tlog.Infof(\"failed to initialize stackdriver exporter: %+v\", err)\n\t\t} else {\n\t\t\ttrace.RegisterExporter(exporter)\n\t\t\tlog.Info(\"registered Stackdriver tracing\")\n\n\t\t\t// Register the views to collect server stats.\n\t\t\tinitStats(exporter)\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver exporter\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver exporter after retrying, giving up\")\n}\n\nfunc initTracing() {\n\tinitJaegerTracing()\n\tinitStackdriverTracing()\n}\n\nfunc initProfiling(service, version string) {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\tif err := profiler.Start(profiler.Config{\n\t\t\tService:        service,\n\t\t\tServiceVersion: version,\n\t\t\t// ProjectID must be set if not running on GCP.\n\t\t\t// ProjectID: \"my-project\",\n\t\t}); err != nil {\n\t\t\tlog.Warnf(\"failed to start profiler: %+v\", err)\n\t\t} else {\n\t\t\tlog.Info(\"started Stackdriver profiler\")\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver profiler\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver profiler after retrying, giving up\")\n}\n\nfunc mustMapEnv(target *string, envKey string) {\n\tv := os.Getenv(envKey)\n\tif v == \"\" {\n\t\tpanic(fmt.Sprintf(\"environment variable %q not set\", envKey))\n\t}\n\t*target = v\n}\n\nfunc (cs *checkoutService) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {\n\treturn &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil\n}\n\nfunc (cs *checkoutService) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error {\n\treturn status.Errorf(codes.Unimplemented, \"health check via Watch not implemented\")\n}\n\nfunc (cs *checkoutService) PlaceOrder(ctx context.Context, req *pb.PlaceOrderRequest) (*pb.PlaceOrderResponse, error) {\n\tlog.Infof(\"[PlaceOrder] user_id=%q user_currency=%q\", req.UserId, req.UserCurrency)\n\n\torderID, err := uuid.NewUUID()\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Internal, \"failed to generate order uuid\")\n\t}\n\n\tprep, err := cs.prepareOrderItemsAndShippingQuoteFromCart(ctx, req.UserId, req.UserCurrency, req.Address)\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Internal, err.Error())\n\t}\n\n\ttotal := pb.Money{CurrencyCode: req.UserCurrency,\n\t\tUnits: 0,\n\t\tNanos: 0}\n\ttotal = money.Must(money.Sum(total, *prep.shippingCostLocalized))\n\tfor _, it := range prep.orderItems {\n\t\tmultPrice := money.MultiplySlow(*it.Cost, uint32(it.GetItem().GetQuantity()))\n\t\ttotal = money.Must(money.Sum(total, multPrice))\n\t}\n\n\ttxID, err := cs.chargeCard(ctx, &total, req.CreditCard)\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Internal, \"failed to charge card: %+v\", err)\n\t}\n\tlog.Infof(\"payment went through (transaction_id: %s)\", txID)\n\n\tshippingTrackingID, err := cs.shipOrder(ctx, req.Address, prep.cartItems)\n\tif err != nil {\n\t\treturn nil, status.Errorf(codes.Unavailable, \"shipping error: %+v\", err)\n\t}\n\n\t_ = cs.emptyUserCart(ctx, req.UserId)\n\n\torderResult := &pb.OrderResult{\n\t\tOrderId:            orderID.String(),\n\t\tShippingTrackingId: shippingTrackingID,\n\t\tShippingCost:       prep.shippingCostLocalized,\n\t\tShippingAddress:    req.Address,\n\t\tItems:              prep.orderItems,\n\t}\n\n\tif err := cs.sendOrderConfirmation(ctx, req.Email, orderResult); err != nil {\n\t\tlog.Warnf(\"failed to send order confirmation to %q: %+v\", req.Email, err)\n\t} else {\n\t\tlog.Infof(\"order confirmation email sent to %q\", req.Email)\n\t}\n\tresp := &pb.PlaceOrderResponse{Order: orderResult}\n\treturn resp, nil\n}\n\ntype orderPrep struct {\n\torderItems            []*pb.OrderItem\n\tcartItems             []*pb.CartItem\n\tshippingCostLocalized *pb.Money\n}\n\nfunc (cs *checkoutService) prepareOrderItemsAndShippingQuoteFromCart(ctx context.Context, userID, userCurrency string, address *pb.Address) (orderPrep, error) {\n\tvar out orderPrep\n\tcartItems, err := cs.getUserCart(ctx, userID)\n\tif err != nil {\n\t\treturn out, fmt.Errorf(\"cart failure: %+v\", err)\n\t}\n\torderItems, err := cs.prepOrderItems(ctx, cartItems, userCurrency)\n\tif err != nil {\n\t\treturn out, fmt.Errorf(\"failed to prepare order: %+v\", err)\n\t}\n\tshippingUSD, err := cs.quoteShipping(ctx, address, cartItems)\n\tif err != nil {\n\t\treturn out, fmt.Errorf(\"shipping quote failure: %+v\", err)\n\t}\n\tshippingPrice, err := cs.convertCurrency(ctx, shippingUSD, userCurrency)\n\tif err != nil {\n\t\treturn out, fmt.Errorf(\"failed to convert shipping cost to currency: %+v\", err)\n\t}\n\n\tout.shippingCostLocalized = shippingPrice\n\tout.cartItems = cartItems\n\tout.orderItems = orderItems\n\treturn out, nil\n}\n\nfunc (cs *checkoutService) quoteShipping(ctx context.Context, address *pb.Address, items []*pb.CartItem) (*pb.Money, error) {\n\tconn, err := grpc.DialContext(ctx, cs.shippingSvcAddr,\n\t\tgrpc.WithInsecure(),\n\t\tgrpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not connect shipping service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\n\tshippingQuote, err := pb.NewShippingServiceClient(conn).\n\t\tGetQuote(ctx, &pb.GetQuoteRequest{\n\t\t\tAddress: address,\n\t\t\tItems:   items})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get shipping quote: %+v\", err)\n\t}\n\treturn shippingQuote.GetCostUsd(), nil\n}\n\nfunc (cs *checkoutService) getUserCart(ctx context.Context, userID string) ([]*pb.CartItem, error) {\n\tconn, err := grpc.DialContext(ctx, cs.cartSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not connect cart service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\n\tcart, err := pb.NewCartServiceClient(conn).GetCart(ctx, &pb.GetCartRequest{UserId: userID})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get user cart during checkout: %+v\", err)\n\t}\n\treturn cart.GetItems(), nil\n}\n\nfunc (cs *checkoutService) emptyUserCart(ctx context.Context, userID string) error {\n\tconn, err := grpc.DialContext(ctx, cs.cartSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not connect cart service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\n\tif _, err = pb.NewCartServiceClient(conn).EmptyCart(ctx, &pb.EmptyCartRequest{UserId: userID}); err != nil {\n\t\treturn fmt.Errorf(\"failed to empty user cart during checkout: %+v\", err)\n\t}\n\treturn nil\n}\n\nfunc (cs *checkoutService) prepOrderItems(ctx context.Context, items []*pb.CartItem, userCurrency string) ([]*pb.OrderItem, error) {\n\tout := make([]*pb.OrderItem, len(items))\n\n\tconn, err := grpc.DialContext(ctx, cs.productCatalogSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not connect product catalog service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\tcl := pb.NewProductCatalogServiceClient(conn)\n\n\tfor i, item := range items {\n\t\tproduct, err := cl.GetProduct(ctx, &pb.GetProductRequest{Id: item.GetProductId()})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get product #%q\", item.GetProductId())\n\t\t}\n\t\tprice, err := cs.convertCurrency(ctx, product.GetPriceUsd(), userCurrency)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to convert price of %q to %s\", item.GetProductId(), userCurrency)\n\t\t}\n\t\tout[i] = &pb.OrderItem{\n\t\t\tItem: item,\n\t\t\tCost: price}\n\t}\n\treturn out, nil\n}\n\nfunc (cs *checkoutService) convertCurrency(ctx context.Context, from *pb.Money, toCurrency string) (*pb.Money, error) {\n\tconn, err := grpc.DialContext(ctx, cs.currencySvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not connect currency service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\tresult, err := pb.NewCurrencyServiceClient(conn).Convert(context.TODO(), &pb.CurrencyConversionRequest{\n\t\tFrom:   from,\n\t\tToCode: toCurrency})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to convert currency: %+v\", err)\n\t}\n\treturn result, err\n}\n\nfunc (cs *checkoutService) chargeCard(ctx context.Context, amount *pb.Money, paymentInfo *pb.CreditCardInfo) (string, error) {\n\tconn, err := grpc.DialContext(ctx, cs.paymentSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to connect payment service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\n\tpaymentResp, err := pb.NewPaymentServiceClient(conn).Charge(ctx, &pb.ChargeRequest{\n\t\tAmount:     amount,\n\t\tCreditCard: paymentInfo})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"could not charge the card: %+v\", err)\n\t}\n\treturn paymentResp.GetTransactionId(), nil\n}\n\nfunc (cs *checkoutService) sendOrderConfirmation(ctx context.Context, email string, order *pb.OrderResult) error {\n\tconn, err := grpc.DialContext(ctx, cs.emailSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to connect email service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\t_, err = pb.NewEmailServiceClient(conn).SendOrderConfirmation(ctx, &pb.SendOrderConfirmationRequest{\n\t\tEmail: email,\n\t\tOrder: order})\n\treturn err\n}\n\nfunc (cs *checkoutService) shipOrder(ctx context.Context, address *pb.Address, items []*pb.CartItem) (string, error) {\n\tconn, err := grpc.DialContext(ctx, cs.shippingSvcAddr, grpc.WithInsecure(), grpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to connect email service: %+v\", err)\n\t}\n\tdefer conn.Close()\n\tresp, err := pb.NewShippingServiceClient(conn).ShipOrder(ctx, &pb.ShipOrderRequest{\n\t\tAddress: address,\n\t\tItems:   items})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"shipment failed: %+v\", err)\n\t}\n\treturn resp.GetTrackingId(), nil\n}\n\n// TODO: Dial and create client once, reuse.\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/money/money.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage money\n\nimport (\n\t\"errors\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto\"\n)\n\nconst (\n\tnanosMin = -999999999\n\tnanosMax = +999999999\n\tnanosMod = 1000000000\n)\n\nvar (\n\tErrInvalidValue        = errors.New(\"one of the specified money values is invalid\")\n\tErrMismatchingCurrency = errors.New(\"mismatching currency codes\")\n)\n\n// IsValid checks if specified value has a valid units/nanos signs and ranges.\nfunc IsValid(m pb.Money) bool {\n\treturn signMatches(m) && validNanos(m.GetNanos())\n}\n\nfunc signMatches(m pb.Money) bool {\n\treturn m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0)\n}\n\nfunc validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax }\n\n// IsZero returns true if the specified money value is equal to zero.\nfunc IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 }\n\n// IsPositive returns true if the specified money value is valid and is\n// positive.\nfunc IsPositive(m pb.Money) bool {\n\treturn IsValid(m) && m.GetUnits() > 0 || (m.GetUnits() == 0 && m.GetNanos() > 0)\n}\n\n// IsNegative returns true if the specified money value is valid and is\n// negative.\nfunc IsNegative(m pb.Money) bool {\n\treturn IsValid(m) && m.GetUnits() < 0 || (m.GetUnits() == 0 && m.GetNanos() < 0)\n}\n\n// AreSameCurrency returns true if values l and r have a currency code and\n// they are the same values.\nfunc AreSameCurrency(l, r pb.Money) bool {\n\treturn l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetCurrencyCode() != \"\"\n}\n\n// AreEquals returns true if values l and r are the equal, including the\n// currency. This does not check validity of the provided values.\nfunc AreEquals(l, r pb.Money) bool {\n\treturn l.GetCurrencyCode() == r.GetCurrencyCode() &&\n\t\tl.GetUnits() == r.GetUnits() && l.GetNanos() == r.GetNanos()\n}\n\n// Negate returns the same amount with the sign negated.\nfunc Negate(m pb.Money) pb.Money {\n\treturn pb.Money{\n\t\tUnits:        -m.GetUnits(),\n\t\tNanos:        -m.GetNanos(),\n\t\tCurrencyCode: m.GetCurrencyCode()}\n}\n\n// Must panics if the given error is not nil. This can be used with other\n// functions like: \"m := Must(Sum(a,b))\".\nfunc Must(v pb.Money, err error) pb.Money {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn v\n}\n\n// Sum adds two values. Returns an error if one of the values are invalid or\n// currency codes are not matching (unless currency code is unspecified for\n// both).\nfunc Sum(l, r pb.Money) (pb.Money, error) {\n\tif !IsValid(l) || !IsValid(r) {\n\t\treturn pb.Money{}, ErrInvalidValue\n\t} else if l.GetCurrencyCode() != r.GetCurrencyCode() {\n\t\treturn pb.Money{}, ErrMismatchingCurrency\n\t}\n\tunits := l.GetUnits() + r.GetUnits()\n\tnanos := l.GetNanos() + r.GetNanos()\n\n\tif (units == 0 && nanos == 0) || (units > 0 && nanos >= 0) || (units < 0 && nanos <= 0) {\n\t\t// same sign <units, nanos>\n\t\tunits += int64(nanos / nanosMod)\n\t\tnanos = nanos % nanosMod\n\t} else {\n\t\t// different sign. nanos guaranteed to not to go over the limit\n\t\tif units > 0 {\n\t\t\tunits--\n\t\t\tnanos += nanosMod\n\t\t} else {\n\t\t\tunits++\n\t\t\tnanos -= nanosMod\n\t\t}\n\t}\n\n\treturn pb.Money{\n\t\tUnits:        units,\n\t\tNanos:        nanos,\n\t\tCurrencyCode: l.GetCurrencyCode()}, nil\n}\n\n// MultiplySlow is a slow multiplication operation done through adding the value\n// to itself n-1 times.\nfunc MultiplySlow(m pb.Money, n uint32) pb.Money {\n\tout := m\n\tfor n > 1 {\n\t\tout = Must(Sum(out, m))\n\t\tn--\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "microservices-demo/src/checkoutservice/money/money_test.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage money\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/checkoutservice/genproto\"\n)\n\nfunc mmc(u int64, n int32, c string) pb.Money { return pb.Money{Units: u, Nanos: n, CurrencyCode: c} }\nfunc mm(u int64, n int32) pb.Money            { return mmc(u, n, \"\") }\n\nfunc TestIsValid(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"valid -/-\", mm(-981273891273, -999999999), true},\n\t\t{\"invalid -/+\", mm(-981273891273, +999999999), false},\n\t\t{\"valid +/+\", mm(981273891273, 999999999), true},\n\t\t{\"invalid +/-\", mm(981273891273, -999999999), false},\n\t\t{\"invalid +/+overflow\", mm(3, 1000000000), false},\n\t\t{\"invalid +/-overflow\", mm(3, -1000000000), false},\n\t\t{\"invalid -/+overflow\", mm(-3, 1000000000), false},\n\t\t{\"invalid -/-overflow\", mm(-3, -1000000000), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsValid(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsValid(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsZero(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), true},\n\t\t{\"not-zero (-/+)\", mm(-1, +1), false},\n\t\t{\"not-zero (-/-)\", mm(-1, -1), false},\n\t\t{\"not-zero (+/+)\", mm(+1, +1), false},\n\t\t{\"not-zero (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsZero(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsZero(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsPositive(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), false},\n\t\t{\"positive (+/+)\", mm(+1, +1), true},\n\t\t{\"invalid (-/+)\", mm(-1, +1), false},\n\t\t{\"negative (-/-)\", mm(-1, -1), false},\n\t\t{\"invalid (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsPositive(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsPositive(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsNegative(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), false},\n\t\t{\"positive (+/+)\", mm(+1, +1), false},\n\t\t{\"invalid (-/+)\", mm(-1, +1), false},\n\t\t{\"negative (-/-)\", mm(-1, -1), true},\n\t\t{\"invalid (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsNegative(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsNegative(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAreSameCurrency(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\"both empty currency\", args{mmc(1, 0, \"\"), mmc(2, 0, \"\")}, false},\n\t\t{\"left empty currency\", args{mmc(1, 0, \"\"), mmc(2, 0, \"USD\")}, false},\n\t\t{\"right empty currency\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"\")}, false},\n\t\t{\"mismatching\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"CAD\")}, false},\n\t\t{\"matching\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"USD\")}, true},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want {\n\t\t\t\tt.Errorf(\"AreSameCurrency([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAreEquals(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\"equals\", args{mmc(1, 2, \"USD\"), mmc(1, 2, \"USD\")}, true},\n\t\t{\"mismatching currency\", args{mmc(1, 2, \"USD\"), mmc(1, 2, \"CAD\")}, false},\n\t\t{\"mismatching units\", args{mmc(10, 20, \"USD\"), mmc(1, 20, \"USD\")}, false},\n\t\t{\"mismatching nanos\", args{mmc(1, 2, \"USD\"), mmc(1, 20, \"USD\")}, false},\n\t\t{\"negated\", args{mmc(1, 2, \"USD\"), mmc(-1, -2, \"USD\")}, false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := AreEquals(tt.args.l, tt.args.r); got != tt.want {\n\t\t\t\tt.Errorf(\"AreEquals([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNegate(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant pb.Money\n\t}{\n\t\t{\"zero\", mm(0, 0), mm(0, 0)},\n\t\t{\"negative\", mm(-1, -200), mm(1, 200)},\n\t\t{\"positive\", mm(1, 200), mm(-1, -200)},\n\t\t{\"carries currency code\", mmc(0, 0, \"XXX\"), mmc(0, 0, \"XXX\")},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Negate(tt.in); !AreEquals(got, tt.want) {\n\t\t\t\tt.Errorf(\"Negate([%v]) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMust_pass(t *testing.T) {\n\tv := Must(mm(2, 3), nil)\n\tif !AreEquals(v, mm(2, 3)) {\n\t\tt.Errorf(\"returned the wrong value: %v\", v)\n\t}\n}\n\nfunc TestMust_panic(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tt.Logf(\"panic captured: %v\", r)\n\t\t}\n\t}()\n\tMust(mm(2, 3), fmt.Errorf(\"some error\"))\n\tt.Fatal(\"this should not have executed due to the panic above\")\n}\n\nfunc TestSum(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\targs    args\n\t\twant    pb.Money\n\t\twantErr error\n\t}{\n\t\t{\"0+0=0\", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil},\n\t\t{\"Error: currency code on left\", args{mmc(0, 0, \"XXX\"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: currency code on right\", args{mm(0, 0), mmc(0, 0, \"YYY\")}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: currency code mismatch\", args{mmc(0, 0, \"AAA\"), mmc(0, 0, \"BBB\")}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: invalid +/-\", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"Error: invalid -/+\", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"Error: invalid nanos\", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"both positive (no carry)\", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil},\n\t\t{\"both positive (nanos=max)\", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil},\n\t\t{\"both positive (carry)\", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil},\n\t\t{\"both negative (no carry)\", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil},\n\t\t{\"both negative (carry)\", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil},\n\t\t{\"mixed (larger positive, just decimals)\", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil},\n\t\t{\"mixed (larger negative, just decimals)\", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil},\n\t\t{\"mixed (larger positive, no borrow)\", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil},\n\t\t{\"mixed (larger positive, with borrow)\", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil},\n\t\t{\"mixed (larger negative, no borrow)\", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil},\n\t\t{\"mixed (larger negative, with borrow)\", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil},\n\t\t{\"0+negative\", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil},\n\t\t{\"negative+0\", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := Sum(tt.args.l, tt.args.r)\n\t\t\tif err != tt.wantErr {\n\t\t\t\tt.Errorf(\"Sum([%v],[%v]): expected err=\\\"%v\\\" got=\\\"%v\\\"\", tt.args.l, tt.args.r, tt.wantErr, err)\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Sum([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/.dockerignore",
    "content": "client.js\nnode_modules/\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/.gitignore",
    "content": "node_modules/\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM node:18-alpine as base\n\nFROM base as builder\n\n# Some packages (e.g. @google-cloud/profiler) require additional\n# deps for post-install scripts\nRUN apk add --update --no-cache \\\n    python3 \\\n    make \\\n    g++\n\nWORKDIR /usr/src/app\n\nCOPY package*.json ./\n\nRUN npm install --only=production\n\nFROM base\n\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\n\nWORKDIR /usr/src/app\n\nCOPY --from=builder /usr/src/app/node_modules ./node_modules\n\nCOPY . .\n\nEXPOSE 7000\n\nENTRYPOINT [ \"node\", \"server.js\" ]\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/client.js",
    "content": "/*\n *\n * Copyright 2015 gRPC authors.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\nrequire('@google-cloud/trace-agent').start();\n\nconst path = require('path');\nconst grpc = require('grpc');\nconst leftPad = require('left-pad');\nconst pino = require('pino');\n\nconst PROTO_PATH = path.join(__dirname, './proto/demo.proto');\nconst PORT = 7000;\n\nconst shopProto = grpc.load(PROTO_PATH).hipstershop;\nconst client = new shopProto.CurrencyService(`localhost:${PORT}`,\n  grpc.credentials.createInsecure());\n\nconst logger = pino({\n  name: 'currencyservice-client',\n  messageKey: 'message',\n  changeLevelName: 'severity',\n  useLevelLabels: true\n});\n\nconst request = {\n  from: {\n    currency_code: 'CHF',\n    units: 300,\n    nanos: 0\n  },\n  to_code: 'EUR'\n};\n\nfunction _moneyToString (m) {\n  return `${m.units}.${m.nanos.toString().padStart(9,'0')} ${m.currency_code}`;\n}\n\nclient.getSupportedCurrencies({}, (err, response) => {\n  if (err) {\n    logger.error(`Error in getSupportedCurrencies: ${err}`);\n  } else {\n    logger.info(`Currency codes: ${response.currency_codes}`);\n  }\n});\n\nclient.convert(request, (err, response) => {\n  if (err) {\n    logger.error(`Error in convert: ${err}`);\n  } else {\n    logger.log(`Convert: ${_moneyToString(request.from)} to ${_moneyToString(response)}`);\n  }\n});\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/data/currency_conversion.json",
    "content": "{\n  \"EUR\": \"1.0\",\n  \"USD\": \"1.1305\",\n  \"JPY\": \"126.40\",\n  \"BGN\": \"1.9558\",\n  \"CZK\": \"25.592\",\n  \"DKK\": \"7.4609\",\n  \"GBP\": \"0.85970\",\n  \"HUF\": \"315.51\",\n  \"PLN\": \"4.2996\",\n  \"RON\": \"4.7463\",\n  \"SEK\": \"10.5375\",\n  \"CHF\": \"1.1360\",\n  \"ISK\": \"136.80\",\n  \"NOK\": \"9.8040\",\n  \"HRK\": \"7.4210\",\n  \"RUB\": \"74.4208\",\n  \"TRY\": \"6.1247\",\n  \"AUD\": \"1.6072\",\n  \"BRL\": \"4.2682\",\n  \"CAD\": \"1.5128\",\n  \"CNY\": \"7.5857\",\n  \"HKD\": \"8.8743\",\n  \"IDR\": \"15999.40\",\n  \"ILS\": \"4.0875\",\n  \"INR\": \"79.4320\",\n  \"KRW\": \"1275.05\",\n  \"MXN\": \"21.7999\",\n  \"MYR\": \"4.6289\",\n  \"NZD\": \"1.6679\",\n  \"PHP\": \"59.083\",\n  \"SGD\": \"1.5349\",\n  \"THB\": \"36.012\",\n  \"ZAR\": \"16.0583\"\n}"
  },
  {
    "path": "microservices-demo/src/currencyservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_currencyservice_genproto]\n\n# protos are loaded dynamically for node, simply copies over the proto.\nmkdir -p proto\ncp -r ../../pb/* ./proto\n\n# [END gke_currencyservice_genproto]"
  },
  {
    "path": "microservices-demo/src/currencyservice/package.json",
    "content": "{\n  \"name\": \"grpc-currency-service\",\n  \"version\": \"0.1.0\",\n  \"description\": \"A gRPC currency conversion microservice\",\n  \"repository\": \"https://github.com/GoogleCloudPlatform/microservices-demo\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Warn: no test specified\\\" && exit 0\",\n    \"lint\": \"semistandard *.js\"\n  },\n  \"license\": \"Apache-2.0\",\n  \"dependencies\": {\n    \"@google-cloud/debug-agent\": \"5.2.9\",\n    \"@google-cloud/profiler\": \"4.2.0\",\n    \"@google-cloud/trace-agent\": \"5.1.6\",\n    \"@grpc/grpc-js\": \"1.6.11\",\n    \"@grpc/proto-loader\": \"0.6.13\",\n    \"async\": \"3.2.4\",\n    \"google-protobuf\": \"3.20.1\",\n    \"pino\": \"5.17.0\",\n    \"request\": \"2.88.2\",\n    \"xml2js\": \"0.4.23\"\n  },\n  \"devDependencies\": {\n    \"semistandard\": \"16.0.1\"\n  }\n}\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/proto/demo.proto",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\npackage hipstershop;\n\n// -----------------Cart service-----------------\n\nservice CartService {\n    rpc AddItem(AddItemRequest) returns (Empty) {}\n    rpc GetCart(GetCartRequest) returns (Cart) {}\n    rpc EmptyCart(EmptyCartRequest) returns (Empty) {}\n}\n\nmessage CartItem {\n    string product_id = 1;\n    int32  quantity = 2;\n}\n\nmessage AddItemRequest {\n    string user_id = 1;\n    CartItem item = 2;\n}\n\nmessage EmptyCartRequest {\n    string user_id = 1;\n}\n\nmessage GetCartRequest {\n    string user_id = 1;\n}\n\nmessage Cart {\n    string user_id = 1;\n    repeated CartItem items = 2;\n}\n\nmessage Empty {}\n\n// ---------------Recommendation service----------\n\nservice RecommendationService {\n  rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){}\n}\n\nmessage ListRecommendationsRequest {\n    string user_id = 1;\n    repeated string product_ids = 2;\n}\n\nmessage ListRecommendationsResponse {\n    repeated string product_ids = 1;\n}\n\n// ---------------Product Catalog----------------\n\nservice ProductCatalogService {\n    rpc ListProducts(Empty) returns (ListProductsResponse) {}\n    rpc GetProduct(GetProductRequest) returns (Product) {}\n    rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {}\n}\n\nmessage Product {\n    string id = 1;\n    string name = 2;\n    string description = 3;\n    string picture = 4;\n    Money price_usd = 5;\n\n    // Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n    // other related products.\n    repeated string categories = 6;\n}\n\nmessage ListProductsResponse {\n    repeated Product products = 1;\n}\n\nmessage GetProductRequest {\n    string id = 1;\n}\n\nmessage SearchProductsRequest {\n    string query = 1;\n}\n\nmessage SearchProductsResponse {\n    repeated Product results = 1;\n}\n\n// ---------------Shipping Service----------\n\nservice ShippingService {\n    rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {}\n    rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {}\n}\n\nmessage GetQuoteRequest {\n    Address address = 1;\n    repeated CartItem items = 2;\n}\n\nmessage GetQuoteResponse {\n    Money cost_usd = 1;\n}\n\nmessage ShipOrderRequest {\n    Address address = 1;\n    repeated CartItem items = 2;\n}\n\nmessage ShipOrderResponse {\n    string tracking_id = 1;\n}\n\nmessage Address {\n    string street_address = 1;\n    string city = 2;\n    string state = 3;\n    string country = 4;\n    int32 zip_code = 5;\n}\n\n// -----------------Currency service-----------------\n\nservice CurrencyService {\n    rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {}\n    rpc Convert(CurrencyConversionRequest) returns (Money) {}\n}\n\n// Represents an amount of money with its currency type.\nmessage Money {\n    // The 3-letter currency code defined in ISO 4217.\n    string currency_code = 1;\n\n    // The whole units of the amount.\n    // For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n    int64 units = 2;\n\n    // Number of nano (10^-9) units of the amount.\n    // The value must be between -999,999,999 and +999,999,999 inclusive.\n    // If `units` is positive, `nanos` must be positive or zero.\n    // If `units` is zero, `nanos` can be positive, zero, or negative.\n    // If `units` is negative, `nanos` must be negative or zero.\n    // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n    int32 nanos = 3;\n}\n\nmessage GetSupportedCurrenciesResponse {\n    // The 3-letter currency code defined in ISO 4217.\n    repeated string currency_codes = 1;\n}\n\nmessage CurrencyConversionRequest {\n    Money from = 1;\n\n    // The 3-letter currency code defined in ISO 4217.\n    string to_code = 2;\n}\n\n// -------------Payment service-----------------\n\nservice PaymentService {\n    rpc Charge(ChargeRequest) returns (ChargeResponse) {}\n}\n\nmessage CreditCardInfo {\n    string credit_card_number = 1;\n    int32 credit_card_cvv = 2;\n    int32 credit_card_expiration_year = 3;\n    int32 credit_card_expiration_month = 4;\n}\n\nmessage ChargeRequest {\n    Money amount = 1;\n    CreditCardInfo credit_card = 2;\n}\n\nmessage ChargeResponse {\n    string transaction_id = 1;\n}\n\n// -------------Email service-----------------\n\nservice EmailService {\n    rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {}\n}\n\nmessage OrderItem {\n    CartItem item = 1;\n    Money cost = 2;\n}\n\nmessage OrderResult {\n    string   order_id = 1;\n    string   shipping_tracking_id = 2;\n    Money shipping_cost = 3;\n    Address  shipping_address = 4;\n    repeated OrderItem items = 5;\n}\n\nmessage SendOrderConfirmationRequest {\n    string email = 1;\n    OrderResult order = 2;\n}\n\n\n// -------------Checkout service-----------------\n\nservice CheckoutService {\n    rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {}\n}\n\nmessage PlaceOrderRequest {\n    string user_id = 1;\n    string user_currency = 2;\n\n    Address address = 3;\n    string email = 5;\n    CreditCardInfo credit_card = 6;\n}\n\nmessage PlaceOrderResponse {\n    OrderResult order = 1;\n}\n\n// ------------Ad service------------------\n\nservice AdService {\n    rpc GetAds(AdRequest) returns (AdResponse) {}\n}\n\nmessage AdRequest {\n    // List of important key words from the current page describing the context.\n    repeated string context_keys = 1;\n}\n\nmessage AdResponse {\n    repeated Ad ads = 1;\n}\n\nmessage Ad {\n    // url to redirect to when an ad is clicked.\n    string redirect_url = 1;\n\n    // short advertisement text to display.\n    string text = 2;\n}\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/proto/grpc/health/v1/health.proto",
    "content": "// Copyright 2015 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// The canonical version of this proto can be found at\n// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto\n\nsyntax = \"proto3\";\n\npackage grpc.health.v1;\n\noption csharp_namespace = \"Grpc.Health.V1\";\noption go_package = \"google.golang.org/grpc/health/grpc_health_v1\";\noption java_multiple_files = true;\noption java_outer_classname = \"HealthProto\";\noption java_package = \"io.grpc.health.v1\";\n\nmessage HealthCheckRequest {\n  string service = 1;\n}\n\nmessage HealthCheckResponse {\n  enum ServingStatus {\n    UNKNOWN = 0;\n    SERVING = 1;\n    NOT_SERVING = 2;\n  }\n  ServingStatus status = 1;\n}\n\nservice Health {\n  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);\n}\n"
  },
  {
    "path": "microservices-demo/src/currencyservice/server.js",
    "content": "/*\n * Copyright 2018 Google LLC.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nif(process.env.DISABLE_PROFILER) {\n  console.log(\"Profiler disabled.\")\n}\nelse {\n  console.log(\"Profiler enabled.\")\n  require('@google-cloud/profiler').start({\n    serviceContext: {\n      service: 'currencyservice',\n      version: '1.0.0'\n    }\n  });\n}\n\n\nif(process.env.DISABLE_TRACING) {\n  console.log(\"Tracing disabled.\")\n}\nelse {\n  console.log(\"Tracing enabled.\")\n  require('@google-cloud/trace-agent').start();\n}\n\nif(process.env.DISABLE_DEBUGGER) {\n  console.log(\"Debugger disabled.\")\n}\nelse {\n  console.log(\"Debugger enabled.\")\n  require('@google-cloud/debug-agent').start({\n    serviceContext: {\n      service: 'currencyservice',\n      version: 'VERSION'\n    }\n  });\n}\n\nconst path = require('path');\nconst grpc = require('@grpc/grpc-js');\nconst pino = require('pino');\nconst protoLoader = require('@grpc/proto-loader');\n\nconst MAIN_PROTO_PATH = path.join(__dirname, './proto/demo.proto');\nconst HEALTH_PROTO_PATH = path.join(__dirname, './proto/grpc/health/v1/health.proto');\n\nconst PORT = process.env.PORT;\n\nconst shopProto = _loadProto(MAIN_PROTO_PATH).hipstershop;\nconst healthProto = _loadProto(HEALTH_PROTO_PATH).grpc.health.v1;\n\nconst logger = pino({\n  name: 'currencyservice-server',\n  messageKey: 'message',\n  changeLevelName: 'severity',\n  useLevelLabels: true\n});\n\n/**\n * Helper function that loads a protobuf file.\n */\nfunction _loadProto (path) {\n  const packageDefinition = protoLoader.loadSync(\n    path,\n    {\n      keepCase: true,\n      longs: String,\n      enums: String,\n      defaults: true,\n      oneofs: true\n    }\n  );\n  return grpc.loadPackageDefinition(packageDefinition);\n}\n\n/**\n * Helper function that gets currency data from a stored JSON file\n * Uses public data from European Central Bank\n */\nfunction _getCurrencyData (callback) {\n  const data = require('./data/currency_conversion.json');\n  callback(data);\n}\n\n/**\n * Helper function that handles decimal/fractional carrying\n */\nfunction _carry (amount) {\n  const fractionSize = Math.pow(10, 9);\n  amount.nanos += (amount.units % 1) * fractionSize;\n  amount.units = Math.floor(amount.units) + Math.floor(amount.nanos / fractionSize);\n  amount.nanos = amount.nanos % fractionSize;\n  return amount;\n}\n\n/**\n * Lists the supported currencies\n */\nfunction getSupportedCurrencies (call, callback) {\n  logger.info('Getting supported currencies...');\n  _getCurrencyData((data) => {\n    callback(null, {currency_codes: Object.keys(data)});\n  });\n}\n\n/**\n * Converts between currencies\n */\nfunction convert (call, callback) {\n  try {\n    _getCurrencyData((data) => {\n      const request = call.request;\n\n      // Convert: from_currency --> EUR\n      const from = request.from;\n      const euros = _carry({\n        units: from.units / data[from.currency_code],\n        nanos: from.nanos / data[from.currency_code]\n      });\n\n      euros.nanos = Math.round(euros.nanos);\n\n      // Convert: EUR --> to_currency\n      const result = _carry({\n        units: euros.units * data[request.to_code],\n        nanos: euros.nanos * data[request.to_code]\n      });\n\n      result.units = Math.floor(result.units);\n      result.nanos = Math.floor(result.nanos);\n      result.currency_code = request.to_code;\n\n      logger.info(`conversion request successful`);\n      callback(null, result);\n    });\n  } catch (err) {\n    logger.error(`conversion request failed: ${err}`);\n    callback(err.message);\n  }\n}\n\n/**\n * Endpoint for health checks\n */\nfunction check (call, callback) {\n  callback(null, { status: 'SERVING' });\n}\n\n/**\n * Starts an RPC server that receives requests for the\n * CurrencyConverter service at the sample server port\n */\nfunction main () {\n  logger.info(`Starting gRPC server on port ${PORT}...`);\n  const server = new grpc.Server();\n  server.addService(shopProto.CurrencyService.service, {getSupportedCurrencies, convert});\n  server.addService(healthProto.Health.service, {check});\n\n  server.bindAsync(\n    `0.0.0.0:${PORT}`,\n    grpc.ServerCredentials.createInsecure(),\n    function() {\n      logger.info(`CurrencyService gRPC server started on port ${PORT}`);\n      server.start();\n    },\n   );\n}\n\nmain();\n"
  },
  {
    "path": "microservices-demo/src/emailservice/.python-version",
    "content": "3.7\n"
  },
  {
    "path": "microservices-demo/src/emailservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM python:3.7-slim as base\n\nFROM base as builder\n\nRUN apt-get -qq update \\\n    && apt-get install -y --no-install-recommends \\\n        g++ \\\n    && rm -rf /var/lib/apt/lists/*\n\n# get packages\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\nFROM base as final\n# Enable unbuffered logging\nENV PYTHONUNBUFFERED=1\n# Enable Profiler\nENV ENABLE_PROFILER=1\n\nRUN apt-get -qq update \\\n    && apt-get install -y --no-install-recommends \\\n        wget\n\n# Download the grpc health probe\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\n\nWORKDIR /email_server\n\n# Grab packages from builder\nCOPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/\n\n# Add the application\nCOPY . .\n\nEXPOSE 8080\nENTRYPOINT [ \"python\", \"email_server.py\" ]\n"
  },
  {
    "path": "microservices-demo/src/emailservice/Procfile",
    "content": "web: python email_server.py\n"
  },
  {
    "path": "microservices-demo/src/emailservice/demo_pb2.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Generated by the protocol buffer compiler.  DO NOT EDIT!\n# source: demo.proto\n\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))\nfrom google.protobuf import descriptor as _descriptor\nfrom google.protobuf import message as _message\nfrom google.protobuf import reflection as _reflection\nfrom google.protobuf import symbol_database as _symbol_database\nfrom google.protobuf import descriptor_pb2\n# @@protoc_insertion_point(imports)\n\n_sym_db = _symbol_database.Default()\n\n\n\n\nDESCRIPTOR = _descriptor.FileDescriptor(\n  name='demo.proto',\n  package='hipstershop',\n  syntax='proto3',\n  serialized_pb=_b('\\n\\ndemo.proto\\x12\\x0bhipstershop\\\"0\\n\\x08\\x43\\x61rtItem\\x12\\x12\\n\\nproduct_id\\x18\\x01 \\x01(\\t\\x12\\x10\\n\\x08quantity\\x18\\x02 \\x01(\\x05\\\"F\\n\\x0e\\x41\\x64\\x64ItemRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12#\\n\\x04item\\x18\\x02 \\x01(\\x0b\\x32\\x15.hipstershop.CartItem\\\"#\\n\\x10\\x45mptyCartRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\\"!\\n\\x0eGetCartRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\\"=\\n\\x04\\x43\\x61rt\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"\\x07\\n\\x05\\x45mpty\\\"B\\n\\x1aListRecommendationsRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12\\x13\\n\\x0bproduct_ids\\x18\\x02 \\x03(\\t\\\"2\\n\\x1bListRecommendationsResponse\\x12\\x13\\n\\x0bproduct_ids\\x18\\x01 \\x03(\\t\\\"p\\n\\x07Product\\x12\\n\\n\\x02id\\x18\\x01 \\x01(\\t\\x12\\x0c\\n\\x04name\\x18\\x02 \\x01(\\t\\x12\\x13\\n\\x0b\\x64\\x65scription\\x18\\x03 \\x01(\\t\\x12\\x0f\\n\\x07picture\\x18\\x04 \\x01(\\t\\x12%\\n\\tprice_usd\\x18\\x05 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\">\\n\\x14ListProductsResponse\\x12&\\n\\x08products\\x18\\x01 \\x03(\\x0b\\x32\\x14.hipstershop.Product\\\"\\x1f\\n\\x11GetProductRequest\\x12\\n\\n\\x02id\\x18\\x01 \\x01(\\t\\\"&\\n\\x15SearchProductsRequest\\x12\\r\\n\\x05query\\x18\\x01 \\x01(\\t\\\"?\\n\\x16SearchProductsResponse\\x12%\\n\\x07results\\x18\\x01 \\x03(\\x0b\\x32\\x14.hipstershop.Product\\\"^\\n\\x0fGetQuoteRequest\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x01 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"8\\n\\x10GetQuoteResponse\\x12$\\n\\x08\\x63ost_usd\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\"_\\n\\x10ShipOrderRequest\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x01 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"(\\n\\x11ShipOrderResponse\\x12\\x13\\n\\x0btracking_id\\x18\\x01 \\x01(\\t\\\"n\\n\\x07\\x41\\x64\\x64ress\\x12\\x18\\n\\x10street_address_1\\x18\\x01 \\x01(\\t\\x12\\x18\\n\\x10street_address_2\\x18\\x02 \\x01(\\t\\x12\\x0c\\n\\x04\\x63ity\\x18\\x03 \\x01(\\t\\x12\\x0f\\n\\x07\\x63ountry\\x18\\x04 \\x01(\\t\\x12\\x10\\n\\x08zip_code\\x18\\x05 \\x01(\\x05\\\"<\\n\\x05Money\\x12\\x15\\n\\rcurrency_code\\x18\\x01 \\x01(\\t\\x12\\r\\n\\x05units\\x18\\x02 \\x01(\\x03\\x12\\r\\n\\x05nanos\\x18\\x03 \\x01(\\x05\\\"8\\n\\x1eGetSupportedCurrenciesResponse\\x12\\x16\\n\\x0e\\x63urrency_codes\\x18\\x01 \\x03(\\t\\\"N\\n\\x19\\x43urrencyConversionRequest\\x12 \\n\\x04\\x66rom\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12\\x0f\\n\\x07to_code\\x18\\x02 \\x01(\\t\\\"\\x90\\x01\\n\\x0e\\x43reditCardInfo\\x12\\x1a\\n\\x12\\x63redit_card_number\\x18\\x01 \\x01(\\t\\x12\\x17\\n\\x0f\\x63redit_card_cvv\\x18\\x02 \\x01(\\x05\\x12#\\n\\x1b\\x63redit_card_expiration_year\\x18\\x03 \\x01(\\x05\\x12$\\n\\x1c\\x63redit_card_expiration_month\\x18\\x04 \\x01(\\x05\\\"e\\n\\rChargeRequest\\x12\\\"\\n\\x06\\x61mount\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12\\x30\\n\\x0b\\x63redit_card\\x18\\x02 \\x01(\\x0b\\x32\\x1b.hipstershop.CreditCardInfo\\\"(\\n\\x0e\\x43hargeResponse\\x12\\x16\\n\\x0etransaction_id\\x18\\x01 \\x01(\\t\\\"R\\n\\tOrderItem\\x12#\\n\\x04item\\x18\\x01 \\x01(\\x0b\\x32\\x15.hipstershop.CartItem\\x12 \\n\\x04\\x63ost\\x18\\x02 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\"\\xbf\\x01\\n\\x0bOrderResult\\x12\\x10\\n\\x08order_id\\x18\\x01 \\x01(\\t\\x12\\x1c\\n\\x14shipping_tracking_id\\x18\\x02 \\x01(\\t\\x12)\\n\\rshipping_cost\\x18\\x03 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12.\\n\\x10shipping_address\\x18\\x04 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12%\\n\\x05items\\x18\\x05 \\x03(\\x0b\\x32\\x16.hipstershop.OrderItem\\\"V\\n\\x1cSendOrderConfirmationRequest\\x12\\r\\n\\x05\\x65mail\\x18\\x01 \\x01(\\t\\x12\\'\\n\\x05order\\x18\\x02 \\x01(\\x0b\\x32\\x18.hipstershop.OrderResult\\\"c\\n\\x12\\x43reateOrderRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12\\x15\\n\\ruser_currency\\x18\\x02 \\x01(\\t\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x03 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\\"g\\n\\x13\\x43reateOrderResponse\\x12%\\n\\x05items\\x18\\x01 \\x03(\\x0b\\x32\\x16.hipstershop.OrderItem\\x12)\\n\\rshipping_cost\\x18\\x02 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\"\\xa3\\x01\\n\\x11PlaceOrderRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12\\x15\\n\\ruser_currency\\x18\\x02 \\x01(\\t\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x03 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12\\r\\n\\x05\\x65mail\\x18\\x05 \\x01(\\t\\x12\\x30\\n\\x0b\\x63redit_card\\x18\\x06 \\x01(\\x0b\\x32\\x1b.hipstershop.CreditCardInfo\\\"=\\n\\x12PlaceOrderResponse\\x12\\'\\n\\x05order\\x18\\x01 \\x01(\\x0b\\x32\\x18.hipstershop.OrderResult2\\xca\\x01\\n\\x0b\\x43\\x61rtService\\x12<\\n\\x07\\x41\\x64\\x64Item\\x12\\x1b.hipstershop.AddItemRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x12;\\n\\x07GetCart\\x12\\x1b.hipstershop.GetCartRequest\\x1a\\x11.hipstershop.Cart\\\"\\x00\\x12@\\n\\tEmptyCart\\x12\\x1d.hipstershop.EmptyCartRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x32\\x83\\x01\\n\\x15RecommendationService\\x12j\\n\\x13ListRecommendations\\x12\\'.hipstershop.ListRecommendationsRequest\\x1a(.hipstershop.ListRecommendationsResponse\\\"\\x00\\x32\\x83\\x02\\n\\x15ProductCatalogService\\x12G\\n\\x0cListProducts\\x12\\x12.hipstershop.Empty\\x1a!.hipstershop.ListProductsResponse\\\"\\x00\\x12\\x44\\n\\nGetProduct\\x12\\x1e.hipstershop.GetProductRequest\\x1a\\x14.hipstershop.Product\\\"\\x00\\x12[\\n\\x0eSearchProducts\\x12\\\".hipstershop.SearchProductsRequest\\x1a#.hipstershop.SearchProductsResponse\\\"\\x00\\x32\\xaa\\x01\\n\\x0fShippingService\\x12I\\n\\x08GetQuote\\x12\\x1c.hipstershop.GetQuoteRequest\\x1a\\x1d.hipstershop.GetQuoteResponse\\\"\\x00\\x12L\\n\\tShipOrder\\x12\\x1d.hipstershop.ShipOrderRequest\\x1a\\x1e.hipstershop.ShipOrderResponse\\\"\\x00\\x32\\xb7\\x01\\n\\x0f\\x43urrencyService\\x12[\\n\\x16GetSupportedCurrencies\\x12\\x12.hipstershop.Empty\\x1a+.hipstershop.GetSupportedCurrenciesResponse\\\"\\x00\\x12G\\n\\x07\\x43onvert\\x12&.hipstershop.CurrencyConversionRequest\\x1a\\x12.hipstershop.Money\\\"\\x00\\x32U\\n\\x0ePaymentService\\x12\\x43\\n\\x06\\x43harge\\x12\\x1a.hipstershop.ChargeRequest\\x1a\\x1b.hipstershop.ChargeResponse\\\"\\x00\\x32h\\n\\x0c\\x45mailService\\x12X\\n\\x15SendOrderConfirmation\\x12).hipstershop.SendOrderConfirmationRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x32\\xb6\\x01\\n\\x0f\\x43heckoutService\\x12R\\n\\x0b\\x43reateOrder\\x12\\x1f.hipstershop.CreateOrderRequest\\x1a .hipstershop.CreateOrderResponse\\\"\\x00\\x12O\\n\\nPlaceOrder\\x12\\x1e.hipstershop.PlaceOrderRequest\\x1a\\x1f.hipstershop.PlaceOrderResponse\\\"\\x00\\x62\\x06proto3')\n)\n\n\n\n\n_CARTITEM = _descriptor.Descriptor(\n  name='CartItem',\n  full_name='hipstershop.CartItem',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='product_id', full_name='hipstershop.CartItem.product_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='quantity', full_name='hipstershop.CartItem.quantity', index=1,\n      number=2, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=27,\n  serialized_end=75,\n)\n\n\n_ADDITEMREQUEST = _descriptor.Descriptor(\n  name='AddItemRequest',\n  full_name='hipstershop.AddItemRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.AddItemRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='item', full_name='hipstershop.AddItemRequest.item', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=77,\n  serialized_end=147,\n)\n\n\n_EMPTYCARTREQUEST = _descriptor.Descriptor(\n  name='EmptyCartRequest',\n  full_name='hipstershop.EmptyCartRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.EmptyCartRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=149,\n  serialized_end=184,\n)\n\n\n_GETCARTREQUEST = _descriptor.Descriptor(\n  name='GetCartRequest',\n  full_name='hipstershop.GetCartRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.GetCartRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=186,\n  serialized_end=219,\n)\n\n\n_CART = _descriptor.Descriptor(\n  name='Cart',\n  full_name='hipstershop.Cart',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.Cart.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.Cart.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=221,\n  serialized_end=282,\n)\n\n\n_EMPTY = _descriptor.Descriptor(\n  name='Empty',\n  full_name='hipstershop.Empty',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=284,\n  serialized_end=291,\n)\n\n\n_LISTRECOMMENDATIONSREQUEST = _descriptor.Descriptor(\n  name='ListRecommendationsRequest',\n  full_name='hipstershop.ListRecommendationsRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.ListRecommendationsRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='product_ids', full_name='hipstershop.ListRecommendationsRequest.product_ids', index=1,\n      number=2, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=293,\n  serialized_end=359,\n)\n\n\n_LISTRECOMMENDATIONSRESPONSE = _descriptor.Descriptor(\n  name='ListRecommendationsResponse',\n  full_name='hipstershop.ListRecommendationsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='product_ids', full_name='hipstershop.ListRecommendationsResponse.product_ids', index=0,\n      number=1, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=361,\n  serialized_end=411,\n)\n\n\n_PRODUCT = _descriptor.Descriptor(\n  name='Product',\n  full_name='hipstershop.Product',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='id', full_name='hipstershop.Product.id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='name', full_name='hipstershop.Product.name', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='description', full_name='hipstershop.Product.description', index=2,\n      number=3, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='picture', full_name='hipstershop.Product.picture', index=3,\n      number=4, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='price_usd', full_name='hipstershop.Product.price_usd', index=4,\n      number=5, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=413,\n  serialized_end=525,\n)\n\n\n_LISTPRODUCTSRESPONSE = _descriptor.Descriptor(\n  name='ListProductsResponse',\n  full_name='hipstershop.ListProductsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='products', full_name='hipstershop.ListProductsResponse.products', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=527,\n  serialized_end=589,\n)\n\n\n_GETPRODUCTREQUEST = _descriptor.Descriptor(\n  name='GetProductRequest',\n  full_name='hipstershop.GetProductRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='id', full_name='hipstershop.GetProductRequest.id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=591,\n  serialized_end=622,\n)\n\n\n_SEARCHPRODUCTSREQUEST = _descriptor.Descriptor(\n  name='SearchProductsRequest',\n  full_name='hipstershop.SearchProductsRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='query', full_name='hipstershop.SearchProductsRequest.query', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=624,\n  serialized_end=662,\n)\n\n\n_SEARCHPRODUCTSRESPONSE = _descriptor.Descriptor(\n  name='SearchProductsResponse',\n  full_name='hipstershop.SearchProductsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='results', full_name='hipstershop.SearchProductsResponse.results', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=664,\n  serialized_end=727,\n)\n\n\n_GETQUOTEREQUEST = _descriptor.Descriptor(\n  name='GetQuoteRequest',\n  full_name='hipstershop.GetQuoteRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.GetQuoteRequest.address', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.GetQuoteRequest.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=729,\n  serialized_end=823,\n)\n\n\n_GETQUOTERESPONSE = _descriptor.Descriptor(\n  name='GetQuoteResponse',\n  full_name='hipstershop.GetQuoteResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='cost_usd', full_name='hipstershop.GetQuoteResponse.cost_usd', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=825,\n  serialized_end=881,\n)\n\n\n_SHIPORDERREQUEST = _descriptor.Descriptor(\n  name='ShipOrderRequest',\n  full_name='hipstershop.ShipOrderRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.ShipOrderRequest.address', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.ShipOrderRequest.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=883,\n  serialized_end=978,\n)\n\n\n_SHIPORDERRESPONSE = _descriptor.Descriptor(\n  name='ShipOrderResponse',\n  full_name='hipstershop.ShipOrderResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='tracking_id', full_name='hipstershop.ShipOrderResponse.tracking_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=980,\n  serialized_end=1020,\n)\n\n\n_ADDRESS = _descriptor.Descriptor(\n  name='Address',\n  full_name='hipstershop.Address',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='street_address_1', full_name='hipstershop.Address.street_address_1', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='street_address_2', full_name='hipstershop.Address.street_address_2', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='city', full_name='hipstershop.Address.city', index=2,\n      number=3, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='country', full_name='hipstershop.Address.country', index=3,\n      number=4, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='zip_code', full_name='hipstershop.Address.zip_code', index=4,\n      number=5, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1022,\n  serialized_end=1132,\n)\n\n\n_MONEY = _descriptor.Descriptor(\n  name='Money',\n  full_name='hipstershop.Money',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='currency_code', full_name='hipstershop.Money.currency_code', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='units', full_name='hipstershop.Money.units', index=1,\n      number=2, type=3, cpp_type=2, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='nanos', full_name='hipstershop.Money.nanos', index=2,\n      number=3, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1134,\n  serialized_end=1194,\n)\n\n\n_GETSUPPORTEDCURRENCIESRESPONSE = _descriptor.Descriptor(\n  name='GetSupportedCurrenciesResponse',\n  full_name='hipstershop.GetSupportedCurrenciesResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='currency_codes', full_name='hipstershop.GetSupportedCurrenciesResponse.currency_codes', index=0,\n      number=1, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1196,\n  serialized_end=1252,\n)\n\n\n_CURRENCYCONVERSIONREQUEST = _descriptor.Descriptor(\n  name='CurrencyConversionRequest',\n  full_name='hipstershop.CurrencyConversionRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='from', full_name='hipstershop.CurrencyConversionRequest.from', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='to_code', full_name='hipstershop.CurrencyConversionRequest.to_code', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1254,\n  serialized_end=1332,\n)\n\n\n_CREDITCARDINFO = _descriptor.Descriptor(\n  name='CreditCardInfo',\n  full_name='hipstershop.CreditCardInfo',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='credit_card_number', full_name='hipstershop.CreditCardInfo.credit_card_number', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_cvv', full_name='hipstershop.CreditCardInfo.credit_card_cvv', index=1,\n      number=2, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_expiration_year', full_name='hipstershop.CreditCardInfo.credit_card_expiration_year', index=2,\n      number=3, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_expiration_month', full_name='hipstershop.CreditCardInfo.credit_card_expiration_month', index=3,\n      number=4, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1335,\n  serialized_end=1479,\n)\n\n\n_CHARGEREQUEST = _descriptor.Descriptor(\n  name='ChargeRequest',\n  full_name='hipstershop.ChargeRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='amount', full_name='hipstershop.ChargeRequest.amount', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card', full_name='hipstershop.ChargeRequest.credit_card', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1481,\n  serialized_end=1582,\n)\n\n\n_CHARGERESPONSE = _descriptor.Descriptor(\n  name='ChargeResponse',\n  full_name='hipstershop.ChargeResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='transaction_id', full_name='hipstershop.ChargeResponse.transaction_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1584,\n  serialized_end=1624,\n)\n\n\n_ORDERITEM = _descriptor.Descriptor(\n  name='OrderItem',\n  full_name='hipstershop.OrderItem',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='item', full_name='hipstershop.OrderItem.item', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='cost', full_name='hipstershop.OrderItem.cost', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1626,\n  serialized_end=1708,\n)\n\n\n_ORDERRESULT = _descriptor.Descriptor(\n  name='OrderResult',\n  full_name='hipstershop.OrderResult',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='order_id', full_name='hipstershop.OrderResult.order_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_tracking_id', full_name='hipstershop.OrderResult.shipping_tracking_id', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_cost', full_name='hipstershop.OrderResult.shipping_cost', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_address', full_name='hipstershop.OrderResult.shipping_address', index=3,\n      number=4, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.OrderResult.items', index=4,\n      number=5, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1711,\n  serialized_end=1902,\n)\n\n\n_SENDORDERCONFIRMATIONREQUEST = _descriptor.Descriptor(\n  name='SendOrderConfirmationRequest',\n  full_name='hipstershop.SendOrderConfirmationRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='email', full_name='hipstershop.SendOrderConfirmationRequest.email', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='order', full_name='hipstershop.SendOrderConfirmationRequest.order', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1904,\n  serialized_end=1990,\n)\n\n\n_CREATEORDERREQUEST = _descriptor.Descriptor(\n  name='CreateOrderRequest',\n  full_name='hipstershop.CreateOrderRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.CreateOrderRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='user_currency', full_name='hipstershop.CreateOrderRequest.user_currency', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.CreateOrderRequest.address', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1992,\n  serialized_end=2091,\n)\n\n\n_CREATEORDERRESPONSE = _descriptor.Descriptor(\n  name='CreateOrderResponse',\n  full_name='hipstershop.CreateOrderResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.CreateOrderResponse.items', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_cost', full_name='hipstershop.CreateOrderResponse.shipping_cost', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2093,\n  serialized_end=2196,\n)\n\n\n_PLACEORDERREQUEST = _descriptor.Descriptor(\n  name='PlaceOrderRequest',\n  full_name='hipstershop.PlaceOrderRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.PlaceOrderRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='user_currency', full_name='hipstershop.PlaceOrderRequest.user_currency', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.PlaceOrderRequest.address', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='email', full_name='hipstershop.PlaceOrderRequest.email', index=3,\n      number=5, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card', full_name='hipstershop.PlaceOrderRequest.credit_card', index=4,\n      number=6, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2199,\n  serialized_end=2362,\n)\n\n\n_PLACEORDERRESPONSE = _descriptor.Descriptor(\n  name='PlaceOrderResponse',\n  full_name='hipstershop.PlaceOrderResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='order', full_name='hipstershop.PlaceOrderResponse.order', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2364,\n  serialized_end=2425,\n)\n\n_ADDITEMREQUEST.fields_by_name['item'].message_type = _CARTITEM\n_CART.fields_by_name['items'].message_type = _CARTITEM\n_PRODUCT.fields_by_name['price_usd'].message_type = _MONEY\n_LISTPRODUCTSRESPONSE.fields_by_name['products'].message_type = _PRODUCT\n_SEARCHPRODUCTSRESPONSE.fields_by_name['results'].message_type = _PRODUCT\n_GETQUOTEREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_GETQUOTEREQUEST.fields_by_name['items'].message_type = _CARTITEM\n_GETQUOTERESPONSE.fields_by_name['cost_usd'].message_type = _MONEY\n_SHIPORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_SHIPORDERREQUEST.fields_by_name['items'].message_type = _CARTITEM\n_CURRENCYCONVERSIONREQUEST.fields_by_name['from'].message_type = _MONEY\n_CHARGEREQUEST.fields_by_name['amount'].message_type = _MONEY\n_CHARGEREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO\n_ORDERITEM.fields_by_name['item'].message_type = _CARTITEM\n_ORDERITEM.fields_by_name['cost'].message_type = _MONEY\n_ORDERRESULT.fields_by_name['shipping_cost'].message_type = _MONEY\n_ORDERRESULT.fields_by_name['shipping_address'].message_type = _ADDRESS\n_ORDERRESULT.fields_by_name['items'].message_type = _ORDERITEM\n_SENDORDERCONFIRMATIONREQUEST.fields_by_name['order'].message_type = _ORDERRESULT\n_CREATEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_CREATEORDERRESPONSE.fields_by_name['items'].message_type = _ORDERITEM\n_CREATEORDERRESPONSE.fields_by_name['shipping_cost'].message_type = _MONEY\n_PLACEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_PLACEORDERREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO\n_PLACEORDERRESPONSE.fields_by_name['order'].message_type = _ORDERRESULT\nDESCRIPTOR.message_types_by_name['CartItem'] = _CARTITEM\nDESCRIPTOR.message_types_by_name['AddItemRequest'] = _ADDITEMREQUEST\nDESCRIPTOR.message_types_by_name['EmptyCartRequest'] = _EMPTYCARTREQUEST\nDESCRIPTOR.message_types_by_name['GetCartRequest'] = _GETCARTREQUEST\nDESCRIPTOR.message_types_by_name['Cart'] = _CART\nDESCRIPTOR.message_types_by_name['Empty'] = _EMPTY\nDESCRIPTOR.message_types_by_name['ListRecommendationsRequest'] = _LISTRECOMMENDATIONSREQUEST\nDESCRIPTOR.message_types_by_name['ListRecommendationsResponse'] = _LISTRECOMMENDATIONSRESPONSE\nDESCRIPTOR.message_types_by_name['Product'] = _PRODUCT\nDESCRIPTOR.message_types_by_name['ListProductsResponse'] = _LISTPRODUCTSRESPONSE\nDESCRIPTOR.message_types_by_name['GetProductRequest'] = _GETPRODUCTREQUEST\nDESCRIPTOR.message_types_by_name['SearchProductsRequest'] = _SEARCHPRODUCTSREQUEST\nDESCRIPTOR.message_types_by_name['SearchProductsResponse'] = _SEARCHPRODUCTSRESPONSE\nDESCRIPTOR.message_types_by_name['GetQuoteRequest'] = _GETQUOTEREQUEST\nDESCRIPTOR.message_types_by_name['GetQuoteResponse'] = _GETQUOTERESPONSE\nDESCRIPTOR.message_types_by_name['ShipOrderRequest'] = _SHIPORDERREQUEST\nDESCRIPTOR.message_types_by_name['ShipOrderResponse'] = _SHIPORDERRESPONSE\nDESCRIPTOR.message_types_by_name['Address'] = _ADDRESS\nDESCRIPTOR.message_types_by_name['Money'] = _MONEY\nDESCRIPTOR.message_types_by_name['GetSupportedCurrenciesResponse'] = _GETSUPPORTEDCURRENCIESRESPONSE\nDESCRIPTOR.message_types_by_name['CurrencyConversionRequest'] = _CURRENCYCONVERSIONREQUEST\nDESCRIPTOR.message_types_by_name['CreditCardInfo'] = _CREDITCARDINFO\nDESCRIPTOR.message_types_by_name['ChargeRequest'] = _CHARGEREQUEST\nDESCRIPTOR.message_types_by_name['ChargeResponse'] = _CHARGERESPONSE\nDESCRIPTOR.message_types_by_name['OrderItem'] = _ORDERITEM\nDESCRIPTOR.message_types_by_name['OrderResult'] = _ORDERRESULT\nDESCRIPTOR.message_types_by_name['SendOrderConfirmationRequest'] = _SENDORDERCONFIRMATIONREQUEST\nDESCRIPTOR.message_types_by_name['CreateOrderRequest'] = _CREATEORDERREQUEST\nDESCRIPTOR.message_types_by_name['CreateOrderResponse'] = _CREATEORDERRESPONSE\nDESCRIPTOR.message_types_by_name['PlaceOrderRequest'] = _PLACEORDERREQUEST\nDESCRIPTOR.message_types_by_name['PlaceOrderResponse'] = _PLACEORDERRESPONSE\n_sym_db.RegisterFileDescriptor(DESCRIPTOR)\n\nCartItem = _reflection.GeneratedProtocolMessageType('CartItem', (_message.Message,), dict(\n  DESCRIPTOR = _CARTITEM,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CartItem)\n  ))\n_sym_db.RegisterMessage(CartItem)\n\nAddItemRequest = _reflection.GeneratedProtocolMessageType('AddItemRequest', (_message.Message,), dict(\n  DESCRIPTOR = _ADDITEMREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.AddItemRequest)\n  ))\n_sym_db.RegisterMessage(AddItemRequest)\n\nEmptyCartRequest = _reflection.GeneratedProtocolMessageType('EmptyCartRequest', (_message.Message,), dict(\n  DESCRIPTOR = _EMPTYCARTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.EmptyCartRequest)\n  ))\n_sym_db.RegisterMessage(EmptyCartRequest)\n\nGetCartRequest = _reflection.GeneratedProtocolMessageType('GetCartRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETCARTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetCartRequest)\n  ))\n_sym_db.RegisterMessage(GetCartRequest)\n\nCart = _reflection.GeneratedProtocolMessageType('Cart', (_message.Message,), dict(\n  DESCRIPTOR = _CART,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Cart)\n  ))\n_sym_db.RegisterMessage(Cart)\n\nEmpty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict(\n  DESCRIPTOR = _EMPTY,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Empty)\n  ))\n_sym_db.RegisterMessage(Empty)\n\nListRecommendationsRequest = _reflection.GeneratedProtocolMessageType('ListRecommendationsRequest', (_message.Message,), dict(\n  DESCRIPTOR = _LISTRECOMMENDATIONSREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsRequest)\n  ))\n_sym_db.RegisterMessage(ListRecommendationsRequest)\n\nListRecommendationsResponse = _reflection.GeneratedProtocolMessageType('ListRecommendationsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _LISTRECOMMENDATIONSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsResponse)\n  ))\n_sym_db.RegisterMessage(ListRecommendationsResponse)\n\nProduct = _reflection.GeneratedProtocolMessageType('Product', (_message.Message,), dict(\n  DESCRIPTOR = _PRODUCT,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Product)\n  ))\n_sym_db.RegisterMessage(Product)\n\nListProductsResponse = _reflection.GeneratedProtocolMessageType('ListProductsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _LISTPRODUCTSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListProductsResponse)\n  ))\n_sym_db.RegisterMessage(ListProductsResponse)\n\nGetProductRequest = _reflection.GeneratedProtocolMessageType('GetProductRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETPRODUCTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetProductRequest)\n  ))\n_sym_db.RegisterMessage(GetProductRequest)\n\nSearchProductsRequest = _reflection.GeneratedProtocolMessageType('SearchProductsRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SEARCHPRODUCTSREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsRequest)\n  ))\n_sym_db.RegisterMessage(SearchProductsRequest)\n\nSearchProductsResponse = _reflection.GeneratedProtocolMessageType('SearchProductsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _SEARCHPRODUCTSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsResponse)\n  ))\n_sym_db.RegisterMessage(SearchProductsResponse)\n\nGetQuoteRequest = _reflection.GeneratedProtocolMessageType('GetQuoteRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETQUOTEREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteRequest)\n  ))\n_sym_db.RegisterMessage(GetQuoteRequest)\n\nGetQuoteResponse = _reflection.GeneratedProtocolMessageType('GetQuoteResponse', (_message.Message,), dict(\n  DESCRIPTOR = _GETQUOTERESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteResponse)\n  ))\n_sym_db.RegisterMessage(GetQuoteResponse)\n\nShipOrderRequest = _reflection.GeneratedProtocolMessageType('ShipOrderRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SHIPORDERREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderRequest)\n  ))\n_sym_db.RegisterMessage(ShipOrderRequest)\n\nShipOrderResponse = _reflection.GeneratedProtocolMessageType('ShipOrderResponse', (_message.Message,), dict(\n  DESCRIPTOR = _SHIPORDERRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderResponse)\n  ))\n_sym_db.RegisterMessage(ShipOrderResponse)\n\nAddress = _reflection.GeneratedProtocolMessageType('Address', (_message.Message,), dict(\n  DESCRIPTOR = _ADDRESS,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Address)\n  ))\n_sym_db.RegisterMessage(Address)\n\nMoney = _reflection.GeneratedProtocolMessageType('Money', (_message.Message,), dict(\n  DESCRIPTOR = _MONEY,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Money)\n  ))\n_sym_db.RegisterMessage(Money)\n\nGetSupportedCurrenciesResponse = _reflection.GeneratedProtocolMessageType('GetSupportedCurrenciesResponse', (_message.Message,), dict(\n  DESCRIPTOR = _GETSUPPORTEDCURRENCIESRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetSupportedCurrenciesResponse)\n  ))\n_sym_db.RegisterMessage(GetSupportedCurrenciesResponse)\n\nCurrencyConversionRequest = _reflection.GeneratedProtocolMessageType('CurrencyConversionRequest', (_message.Message,), dict(\n  DESCRIPTOR = _CURRENCYCONVERSIONREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CurrencyConversionRequest)\n  ))\n_sym_db.RegisterMessage(CurrencyConversionRequest)\n\nCreditCardInfo = _reflection.GeneratedProtocolMessageType('CreditCardInfo', (_message.Message,), dict(\n  DESCRIPTOR = _CREDITCARDINFO,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CreditCardInfo)\n  ))\n_sym_db.RegisterMessage(CreditCardInfo)\n\nChargeRequest = _reflection.GeneratedProtocolMessageType('ChargeRequest', (_message.Message,), dict(\n  DESCRIPTOR = _CHARGEREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ChargeRequest)\n  ))\n_sym_db.RegisterMessage(ChargeRequest)\n\nChargeResponse = _reflection.GeneratedProtocolMessageType('ChargeResponse', (_message.Message,), dict(\n  DESCRIPTOR = _CHARGERESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ChargeResponse)\n  ))\n_sym_db.RegisterMessage(ChargeResponse)\n\nOrderItem = _reflection.GeneratedProtocolMessageType('OrderItem', (_message.Message,), dict(\n  DESCRIPTOR = _ORDERITEM,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.OrderItem)\n  ))\n_sym_db.RegisterMessage(OrderItem)\n\nOrderResult = _reflection.GeneratedProtocolMessageType('OrderResult', (_message.Message,), dict(\n  DESCRIPTOR = _ORDERRESULT,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.OrderResult)\n  ))\n_sym_db.RegisterMessage(OrderResult)\n\nSendOrderConfirmationRequest = _reflection.GeneratedProtocolMessageType('SendOrderConfirmationRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SENDORDERCONFIRMATIONREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SendOrderConfirmationRequest)\n  ))\n_sym_db.RegisterMessage(SendOrderConfirmationRequest)\n\nCreateOrderRequest = _reflection.GeneratedProtocolMessageType('CreateOrderRequest', (_message.Message,), dict(\n  DESCRIPTOR = _CREATEORDERREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CreateOrderRequest)\n  ))\n_sym_db.RegisterMessage(CreateOrderRequest)\n\nCreateOrderResponse = _reflection.GeneratedProtocolMessageType('CreateOrderResponse', (_message.Message,), dict(\n  DESCRIPTOR = _CREATEORDERRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CreateOrderResponse)\n  ))\n_sym_db.RegisterMessage(CreateOrderResponse)\n\nPlaceOrderRequest = _reflection.GeneratedProtocolMessageType('PlaceOrderRequest', (_message.Message,), dict(\n  DESCRIPTOR = _PLACEORDERREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderRequest)\n  ))\n_sym_db.RegisterMessage(PlaceOrderRequest)\n\nPlaceOrderResponse = _reflection.GeneratedProtocolMessageType('PlaceOrderResponse', (_message.Message,), dict(\n  DESCRIPTOR = _PLACEORDERRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderResponse)\n  ))\n_sym_db.RegisterMessage(PlaceOrderResponse)\n\n\n\n_CARTSERVICE = _descriptor.ServiceDescriptor(\n  name='CartService',\n  full_name='hipstershop.CartService',\n  file=DESCRIPTOR,\n  index=0,\n  options=None,\n  serialized_start=2428,\n  serialized_end=2630,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='AddItem',\n    full_name='hipstershop.CartService.AddItem',\n    index=0,\n    containing_service=None,\n    input_type=_ADDITEMREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='GetCart',\n    full_name='hipstershop.CartService.GetCart',\n    index=1,\n    containing_service=None,\n    input_type=_GETCARTREQUEST,\n    output_type=_CART,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='EmptyCart',\n    full_name='hipstershop.CartService.EmptyCart',\n    index=2,\n    containing_service=None,\n    input_type=_EMPTYCARTREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CARTSERVICE)\n\nDESCRIPTOR.services_by_name['CartService'] = _CARTSERVICE\n\n\n_RECOMMENDATIONSERVICE = _descriptor.ServiceDescriptor(\n  name='RecommendationService',\n  full_name='hipstershop.RecommendationService',\n  file=DESCRIPTOR,\n  index=1,\n  options=None,\n  serialized_start=2633,\n  serialized_end=2764,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='ListRecommendations',\n    full_name='hipstershop.RecommendationService.ListRecommendations',\n    index=0,\n    containing_service=None,\n    input_type=_LISTRECOMMENDATIONSREQUEST,\n    output_type=_LISTRECOMMENDATIONSRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_RECOMMENDATIONSERVICE)\n\nDESCRIPTOR.services_by_name['RecommendationService'] = _RECOMMENDATIONSERVICE\n\n\n_PRODUCTCATALOGSERVICE = _descriptor.ServiceDescriptor(\n  name='ProductCatalogService',\n  full_name='hipstershop.ProductCatalogService',\n  file=DESCRIPTOR,\n  index=2,\n  options=None,\n  serialized_start=2767,\n  serialized_end=3026,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='ListProducts',\n    full_name='hipstershop.ProductCatalogService.ListProducts',\n    index=0,\n    containing_service=None,\n    input_type=_EMPTY,\n    output_type=_LISTPRODUCTSRESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='GetProduct',\n    full_name='hipstershop.ProductCatalogService.GetProduct',\n    index=1,\n    containing_service=None,\n    input_type=_GETPRODUCTREQUEST,\n    output_type=_PRODUCT,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='SearchProducts',\n    full_name='hipstershop.ProductCatalogService.SearchProducts',\n    index=2,\n    containing_service=None,\n    input_type=_SEARCHPRODUCTSREQUEST,\n    output_type=_SEARCHPRODUCTSRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_PRODUCTCATALOGSERVICE)\n\nDESCRIPTOR.services_by_name['ProductCatalogService'] = _PRODUCTCATALOGSERVICE\n\n\n_SHIPPINGSERVICE = _descriptor.ServiceDescriptor(\n  name='ShippingService',\n  full_name='hipstershop.ShippingService',\n  file=DESCRIPTOR,\n  index=3,\n  options=None,\n  serialized_start=3029,\n  serialized_end=3199,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='GetQuote',\n    full_name='hipstershop.ShippingService.GetQuote',\n    index=0,\n    containing_service=None,\n    input_type=_GETQUOTEREQUEST,\n    output_type=_GETQUOTERESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='ShipOrder',\n    full_name='hipstershop.ShippingService.ShipOrder',\n    index=1,\n    containing_service=None,\n    input_type=_SHIPORDERREQUEST,\n    output_type=_SHIPORDERRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_SHIPPINGSERVICE)\n\nDESCRIPTOR.services_by_name['ShippingService'] = _SHIPPINGSERVICE\n\n\n_CURRENCYSERVICE = _descriptor.ServiceDescriptor(\n  name='CurrencyService',\n  full_name='hipstershop.CurrencyService',\n  file=DESCRIPTOR,\n  index=4,\n  options=None,\n  serialized_start=3202,\n  serialized_end=3385,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='GetSupportedCurrencies',\n    full_name='hipstershop.CurrencyService.GetSupportedCurrencies',\n    index=0,\n    containing_service=None,\n    input_type=_EMPTY,\n    output_type=_GETSUPPORTEDCURRENCIESRESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='Convert',\n    full_name='hipstershop.CurrencyService.Convert',\n    index=1,\n    containing_service=None,\n    input_type=_CURRENCYCONVERSIONREQUEST,\n    output_type=_MONEY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CURRENCYSERVICE)\n\nDESCRIPTOR.services_by_name['CurrencyService'] = _CURRENCYSERVICE\n\n\n_PAYMENTSERVICE = _descriptor.ServiceDescriptor(\n  name='PaymentService',\n  full_name='hipstershop.PaymentService',\n  file=DESCRIPTOR,\n  index=5,\n  options=None,\n  serialized_start=3387,\n  serialized_end=3472,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='Charge',\n    full_name='hipstershop.PaymentService.Charge',\n    index=0,\n    containing_service=None,\n    input_type=_CHARGEREQUEST,\n    output_type=_CHARGERESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_PAYMENTSERVICE)\n\nDESCRIPTOR.services_by_name['PaymentService'] = _PAYMENTSERVICE\n\n\n_EMAILSERVICE = _descriptor.ServiceDescriptor(\n  name='EmailService',\n  full_name='hipstershop.EmailService',\n  file=DESCRIPTOR,\n  index=6,\n  options=None,\n  serialized_start=3474,\n  serialized_end=3578,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='SendOrderConfirmation',\n    full_name='hipstershop.EmailService.SendOrderConfirmation',\n    index=0,\n    containing_service=None,\n    input_type=_SENDORDERCONFIRMATIONREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_EMAILSERVICE)\n\nDESCRIPTOR.services_by_name['EmailService'] = _EMAILSERVICE\n\n\n_CHECKOUTSERVICE = _descriptor.ServiceDescriptor(\n  name='CheckoutService',\n  full_name='hipstershop.CheckoutService',\n  file=DESCRIPTOR,\n  index=7,\n  options=None,\n  serialized_start=3581,\n  serialized_end=3763,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='CreateOrder',\n    full_name='hipstershop.CheckoutService.CreateOrder',\n    index=0,\n    containing_service=None,\n    input_type=_CREATEORDERREQUEST,\n    output_type=_CREATEORDERRESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='PlaceOrder',\n    full_name='hipstershop.CheckoutService.PlaceOrder',\n    index=1,\n    containing_service=None,\n    input_type=_PLACEORDERREQUEST,\n    output_type=_PLACEORDERRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CHECKOUTSERVICE)\n\nDESCRIPTOR.services_by_name['CheckoutService'] = _CHECKOUTSERVICE\n\n# @@protoc_insertion_point(module_scope)\n"
  },
  {
    "path": "microservices-demo/src/emailservice/demo_pb2_grpc.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!\nimport grpc\n\nimport demo_pb2 as demo__pb2\n\n\nclass CartServiceStub(object):\n  \"\"\"-----------------Cart service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.AddItem = channel.unary_unary(\n        '/hipstershop.CartService/AddItem',\n        request_serializer=demo__pb2.AddItemRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n    self.GetCart = channel.unary_unary(\n        '/hipstershop.CartService/GetCart',\n        request_serializer=demo__pb2.GetCartRequest.SerializeToString,\n        response_deserializer=demo__pb2.Cart.FromString,\n        )\n    self.EmptyCart = channel.unary_unary(\n        '/hipstershop.CartService/EmptyCart',\n        request_serializer=demo__pb2.EmptyCartRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n\n\nclass CartServiceServicer(object):\n  \"\"\"-----------------Cart service-----------------\n\n  \"\"\"\n\n  def AddItem(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def GetCart(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def EmptyCart(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CartServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'AddItem': grpc.unary_unary_rpc_method_handler(\n          servicer.AddItem,\n          request_deserializer=demo__pb2.AddItemRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n      'GetCart': grpc.unary_unary_rpc_method_handler(\n          servicer.GetCart,\n          request_deserializer=demo__pb2.GetCartRequest.FromString,\n          response_serializer=demo__pb2.Cart.SerializeToString,\n      ),\n      'EmptyCart': grpc.unary_unary_rpc_method_handler(\n          servicer.EmptyCart,\n          request_deserializer=demo__pb2.EmptyCartRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CartService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass RecommendationServiceStub(object):\n  \"\"\"---------------Recommendation service----------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.ListRecommendations = channel.unary_unary(\n        '/hipstershop.RecommendationService/ListRecommendations',\n        request_serializer=demo__pb2.ListRecommendationsRequest.SerializeToString,\n        response_deserializer=demo__pb2.ListRecommendationsResponse.FromString,\n        )\n\n\nclass RecommendationServiceServicer(object):\n  \"\"\"---------------Recommendation service----------\n\n  \"\"\"\n\n  def ListRecommendations(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_RecommendationServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'ListRecommendations': grpc.unary_unary_rpc_method_handler(\n          servicer.ListRecommendations,\n          request_deserializer=demo__pb2.ListRecommendationsRequest.FromString,\n          response_serializer=demo__pb2.ListRecommendationsResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.RecommendationService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass ProductCatalogServiceStub(object):\n  \"\"\"---------------Product Catalog----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.ListProducts = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/ListProducts',\n        request_serializer=demo__pb2.Empty.SerializeToString,\n        response_deserializer=demo__pb2.ListProductsResponse.FromString,\n        )\n    self.GetProduct = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/GetProduct',\n        request_serializer=demo__pb2.GetProductRequest.SerializeToString,\n        response_deserializer=demo__pb2.Product.FromString,\n        )\n    self.SearchProducts = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/SearchProducts',\n        request_serializer=demo__pb2.SearchProductsRequest.SerializeToString,\n        response_deserializer=demo__pb2.SearchProductsResponse.FromString,\n        )\n\n\nclass ProductCatalogServiceServicer(object):\n  \"\"\"---------------Product Catalog----------------\n\n  \"\"\"\n\n  def ListProducts(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def GetProduct(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def SearchProducts(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_ProductCatalogServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'ListProducts': grpc.unary_unary_rpc_method_handler(\n          servicer.ListProducts,\n          request_deserializer=demo__pb2.Empty.FromString,\n          response_serializer=demo__pb2.ListProductsResponse.SerializeToString,\n      ),\n      'GetProduct': grpc.unary_unary_rpc_method_handler(\n          servicer.GetProduct,\n          request_deserializer=demo__pb2.GetProductRequest.FromString,\n          response_serializer=demo__pb2.Product.SerializeToString,\n      ),\n      'SearchProducts': grpc.unary_unary_rpc_method_handler(\n          servicer.SearchProducts,\n          request_deserializer=demo__pb2.SearchProductsRequest.FromString,\n          response_serializer=demo__pb2.SearchProductsResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.ProductCatalogService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass ShippingServiceStub(object):\n  \"\"\"---------------Shipping Service----------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.GetQuote = channel.unary_unary(\n        '/hipstershop.ShippingService/GetQuote',\n        request_serializer=demo__pb2.GetQuoteRequest.SerializeToString,\n        response_deserializer=demo__pb2.GetQuoteResponse.FromString,\n        )\n    self.ShipOrder = channel.unary_unary(\n        '/hipstershop.ShippingService/ShipOrder',\n        request_serializer=demo__pb2.ShipOrderRequest.SerializeToString,\n        response_deserializer=demo__pb2.ShipOrderResponse.FromString,\n        )\n\n\nclass ShippingServiceServicer(object):\n  \"\"\"---------------Shipping Service----------\n\n  \"\"\"\n\n  def GetQuote(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def ShipOrder(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_ShippingServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'GetQuote': grpc.unary_unary_rpc_method_handler(\n          servicer.GetQuote,\n          request_deserializer=demo__pb2.GetQuoteRequest.FromString,\n          response_serializer=demo__pb2.GetQuoteResponse.SerializeToString,\n      ),\n      'ShipOrder': grpc.unary_unary_rpc_method_handler(\n          servicer.ShipOrder,\n          request_deserializer=demo__pb2.ShipOrderRequest.FromString,\n          response_serializer=demo__pb2.ShipOrderResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.ShippingService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass CurrencyServiceStub(object):\n  \"\"\"-----------------Currency service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.GetSupportedCurrencies = channel.unary_unary(\n        '/hipstershop.CurrencyService/GetSupportedCurrencies',\n        request_serializer=demo__pb2.Empty.SerializeToString,\n        response_deserializer=demo__pb2.GetSupportedCurrenciesResponse.FromString,\n        )\n    self.Convert = channel.unary_unary(\n        '/hipstershop.CurrencyService/Convert',\n        request_serializer=demo__pb2.CurrencyConversionRequest.SerializeToString,\n        response_deserializer=demo__pb2.Money.FromString,\n        )\n\n\nclass CurrencyServiceServicer(object):\n  \"\"\"-----------------Currency service-----------------\n\n  \"\"\"\n\n  def GetSupportedCurrencies(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def Convert(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CurrencyServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'GetSupportedCurrencies': grpc.unary_unary_rpc_method_handler(\n          servicer.GetSupportedCurrencies,\n          request_deserializer=demo__pb2.Empty.FromString,\n          response_serializer=demo__pb2.GetSupportedCurrenciesResponse.SerializeToString,\n      ),\n      'Convert': grpc.unary_unary_rpc_method_handler(\n          servicer.Convert,\n          request_deserializer=demo__pb2.CurrencyConversionRequest.FromString,\n          response_serializer=demo__pb2.Money.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CurrencyService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass PaymentServiceStub(object):\n  \"\"\"-------------Payment service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.Charge = channel.unary_unary(\n        '/hipstershop.PaymentService/Charge',\n        request_serializer=demo__pb2.ChargeRequest.SerializeToString,\n        response_deserializer=demo__pb2.ChargeResponse.FromString,\n        )\n\n\nclass PaymentServiceServicer(object):\n  \"\"\"-------------Payment service-----------------\n\n  \"\"\"\n\n  def Charge(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_PaymentServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'Charge': grpc.unary_unary_rpc_method_handler(\n          servicer.Charge,\n          request_deserializer=demo__pb2.ChargeRequest.FromString,\n          response_serializer=demo__pb2.ChargeResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.PaymentService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass EmailServiceStub(object):\n  \"\"\"-------------Email service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.SendOrderConfirmation = channel.unary_unary(\n        '/hipstershop.EmailService/SendOrderConfirmation',\n        request_serializer=demo__pb2.SendOrderConfirmationRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n\n\nclass EmailServiceServicer(object):\n  \"\"\"-------------Email service-----------------\n\n  \"\"\"\n\n  def SendOrderConfirmation(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_EmailServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'SendOrderConfirmation': grpc.unary_unary_rpc_method_handler(\n          servicer.SendOrderConfirmation,\n          request_deserializer=demo__pb2.SendOrderConfirmationRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.EmailService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass CheckoutServiceStub(object):\n  \"\"\"-------------Checkout service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.CreateOrder = channel.unary_unary(\n        '/hipstershop.CheckoutService/CreateOrder',\n        request_serializer=demo__pb2.CreateOrderRequest.SerializeToString,\n        response_deserializer=demo__pb2.CreateOrderResponse.FromString,\n        )\n    self.PlaceOrder = channel.unary_unary(\n        '/hipstershop.CheckoutService/PlaceOrder',\n        request_serializer=demo__pb2.PlaceOrderRequest.SerializeToString,\n        response_deserializer=demo__pb2.PlaceOrderResponse.FromString,\n        )\n\n\nclass CheckoutServiceServicer(object):\n  \"\"\"-------------Checkout service-----------------\n\n  \"\"\"\n\n  def CreateOrder(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def PlaceOrder(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CheckoutServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'CreateOrder': grpc.unary_unary_rpc_method_handler(\n          servicer.CreateOrder,\n          request_deserializer=demo__pb2.CreateOrderRequest.FromString,\n          response_serializer=demo__pb2.CreateOrderResponse.SerializeToString,\n      ),\n      'PlaceOrder': grpc.unary_unary_rpc_method_handler(\n          servicer.PlaceOrder,\n          request_deserializer=demo__pb2.PlaceOrderRequest.FromString,\n          response_serializer=demo__pb2.PlaceOrderResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CheckoutService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n"
  },
  {
    "path": "microservices-demo/src/emailservice/email_client.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport grpc\n\nimport demo_pb2\nimport demo_pb2_grpc\n\nfrom logger import getJSONLogger\nlogger = getJSONLogger('emailservice-client')\n\nfrom opencensus.trace.tracer import Tracer\nfrom opencensus.trace.exporters import stackdriver_exporter\nfrom opencensus.trace.ext.grpc import client_interceptor\n\ntry:\n    exporter = stackdriver_exporter.StackdriverExporter()\n    tracer = Tracer(exporter=exporter)\n    tracer_interceptor = client_interceptor.OpenCensusClientInterceptor(tracer, host_port='0.0.0.0:8080')\nexcept:\n    tracer_interceptor = client_interceptor.OpenCensusClientInterceptor()\n\ndef send_confirmation_email(email, order):\n  channel = grpc.insecure_channel('0.0.0.0:8080')\n  channel = grpc.intercept_channel(channel, tracer_interceptor)\n  stub = demo_pb2_grpc.EmailServiceStub(channel)\n  try:\n    response = stub.SendOrderConfirmation(demo_pb2.SendOrderConfirmationRequest(\n      email = email,\n      order = order\n    ))\n    logger.info('Request sent.')\n  except grpc.RpcError as err:\n    logger.error(err.details())\n    logger.error('{}, {}'.format(err.code().name, err.code().value))\n\nif __name__ == '__main__':\n  logger.info('Client for email service.')\n"
  },
  {
    "path": "microservices-demo/src/emailservice/email_server.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom concurrent import futures\nimport argparse\nimport os\nimport sys\nimport time\nimport grpc\nimport traceback\nfrom jinja2 import Environment, FileSystemLoader, select_autoescape, TemplateError\nfrom google.api_core.exceptions import GoogleAPICallError\nfrom google.auth.exceptions import DefaultCredentialsError\n\nimport demo_pb2\nimport demo_pb2_grpc\nfrom grpc_health.v1 import health_pb2\nfrom grpc_health.v1 import health_pb2_grpc\n\nfrom opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter\nfrom opencensus.ext.grpc import server_interceptor\nfrom opencensus.common.transports.async_ import AsyncTransport\nfrom opencensus.trace import samplers\n\n# import googleclouddebugger\nimport googlecloudprofiler\n\nfrom logger import getJSONLogger\nlogger = getJSONLogger('emailservice-server')\n\n# try:\n#     googleclouddebugger.enable(\n#         module='emailserver',\n#         version='1.0.0'\n#     )\n# except:\n#     pass\n\n# Loads confirmation email template from file\nenv = Environment(\n    loader=FileSystemLoader('templates'),\n    autoescape=select_autoescape(['html', 'xml'])\n)\ntemplate = env.get_template('confirmation.html')\n\nclass BaseEmailService(demo_pb2_grpc.EmailServiceServicer):\n  def Check(self, request, context):\n    return health_pb2.HealthCheckResponse(\n      status=health_pb2.HealthCheckResponse.SERVING)\n  \n  def Watch(self, request, context):\n    return health_pb2.HealthCheckResponse(\n      status=health_pb2.HealthCheckResponse.UNIMPLEMENTED)\n\nclass EmailService(BaseEmailService):\n  def __init__(self):\n    raise Exception('cloud mail client not implemented')\n    super().__init__()\n\n  @staticmethod\n  def send_email(client, email_address, content):\n    response = client.send_message(\n      sender = client.sender_path(project_id, region, sender_id),\n      envelope_from_authority = '',\n      header_from_authority = '',\n      envelope_from_address = from_address,\n      simple_message = {\n        \"from\": {\n          \"address_spec\": from_address,\n        },\n        \"to\": [{\n          \"address_spec\": email_address\n        }],\n        \"subject\": \"Your Confirmation Email\",\n        \"html_body\": content\n      }\n    )\n    logger.info(\"Message sent: {}\".format(response.rfc822_message_id))\n\n  def SendOrderConfirmation(self, request, context):\n    email = request.email\n    order = request.order\n\n    try:\n      confirmation = template.render(order = order)\n    except TemplateError as err:\n      context.set_details(\"An error occurred when preparing the confirmation mail.\")\n      logger.error(err.message)\n      context.set_code(grpc.StatusCode.INTERNAL)\n      return demo_pb2.Empty()\n\n    try:\n      EmailService.send_email(self.client, email, confirmation)\n    except GoogleAPICallError as err:\n      context.set_details(\"An error occurred when sending the email.\")\n      print(err.message)\n      context.set_code(grpc.StatusCode.INTERNAL)\n      return demo_pb2.Empty()\n\n    return demo_pb2.Empty()\n\nclass DummyEmailService(BaseEmailService):\n  def SendOrderConfirmation(self, request, context):\n    logger.info('A request to send order confirmation email to {} has been received.'.format(request.email))\n    return demo_pb2.Empty()\n\nclass HealthCheck():\n  def Check(self, request, context):\n    return health_pb2.HealthCheckResponse(\n      status=health_pb2.HealthCheckResponse.SERVING)\n\ndef start(dummy_mode):\n  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),\n                       interceptors=(tracer_interceptor,))\n  service = None\n  if dummy_mode:\n    service = DummyEmailService()\n  else:\n    raise Exception('non-dummy mode not implemented yet')\n\n  demo_pb2_grpc.add_EmailServiceServicer_to_server(service, server)\n  health_pb2_grpc.add_HealthServicer_to_server(service, server)\n\n  port = os.environ.get('PORT', \"8080\")\n  logger.info(\"listening on port: \"+port)\n  server.add_insecure_port('[::]:'+port)\n  server.start()\n  try:\n    while True:\n      time.sleep(3600)\n  except KeyboardInterrupt:\n    server.stop(0)\n\ndef initStackdriverProfiling():\n  project_id = None\n  try:\n    project_id = os.environ[\"GCP_PROJECT_ID\"]\n  except KeyError:\n    # Environment variable not set\n    pass\n\n  for retry in range(1,4):\n    try:\n      if project_id:\n        googlecloudprofiler.start(service='email_server', service_version='1.0.0', verbose=0, project_id=project_id)\n      else:\n        googlecloudprofiler.start(service='email_server', service_version='1.0.0', verbose=0)\n      logger.info(\"Successfully started Stackdriver Profiler.\")\n      return\n    except (BaseException) as exc:\n      logger.info(\"Unable to start Stackdriver Profiler Python agent. \" + str(exc))\n      if (retry < 4):\n        logger.info(\"Sleeping %d to retry initializing Stackdriver Profiler\"%(retry*10))\n        time.sleep (1)\n      else:\n        logger.warning(\"Could not initialize Stackdriver Profiler after retrying, giving up\")\n  return\n\n\nif __name__ == '__main__':\n  logger.info('starting the email service in dummy mode.')\n\n  # Profiler\n  try:\n    if \"DISABLE_PROFILER\" in os.environ:\n      raise KeyError()\n    else:\n      logger.info(\"Profiler enabled.\")\n      initStackdriverProfiling()\n  except KeyError:\n      logger.info(\"Profiler disabled.\")\n\n  # Tracing\n  try:\n    if \"DISABLE_TRACING\" in os.environ:\n      raise KeyError()\n    else:\n      logger.info(\"Tracing enabled.\")\n      sampler = samplers.AlwaysOnSampler()\n      exporter = stackdriver_exporter.StackdriverExporter(\n        project_id=os.environ.get('GCP_PROJECT_ID'),\n        transport=AsyncTransport)\n      tracer_interceptor = server_interceptor.OpenCensusServerInterceptor(sampler, exporter)\n  except (KeyError, DefaultCredentialsError):\n      logger.info(\"Tracing disabled.\")\n      tracer_interceptor = server_interceptor.OpenCensusServerInterceptor()\n  except Exception as e:\n      logger.warn(f\"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled.\") \n      tracer_interceptor = server_interceptor.OpenCensusServerInterceptor()\n  \n  start(dummy_mode = True)\n"
  },
  {
    "path": "microservices-demo/src/emailservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_emailservice_genproto]\n\npython -m grpc_tools.protoc -I../../pb --python_out=. --grpc_python_out=. ../../pb/demo.proto\n\n# [END gke_emailservice_genproto]"
  },
  {
    "path": "microservices-demo/src/emailservice/logger.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport logging\nimport sys\nfrom pythonjsonlogger import jsonlogger\n\n# TODO(yoshifumi) this class is duplicated since other Python services are\n# not sharing the modules for logging.\nclass CustomJsonFormatter(jsonlogger.JsonFormatter):\n  def add_fields(self, log_record, record, message_dict):\n    super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)\n    if not log_record.get('timestamp'):\n      log_record['timestamp'] = record.created\n    if log_record.get('severity'):\n      log_record['severity'] = log_record['severity'].upper()\n    else:\n      log_record['severity'] = record.levelname\n\ndef getJSONLogger(name):\n  logger = logging.getLogger(name)\n  handler = logging.StreamHandler(sys.stdout)\n  formatter = CustomJsonFormatter('(timestamp) (severity) (name) (message)')\n  handler.setFormatter(formatter)\n  logger.addHandler(handler)\n  logger.setLevel(logging.INFO)\n  logger.propagate = False\n  return logger\n"
  },
  {
    "path": "microservices-demo/src/emailservice/pytest.ini",
    "content": "[pytest]\ntestpaths = tests\nconsole_output_style = classic\n"
  },
  {
    "path": "microservices-demo/src/emailservice/requirements.in",
    "content": "google-api-core==2.8.2\ngrpcio-health-checking==1.47.0\ngrpcio==1.47.0\njinja2==3.1.2\nopencensus==0.9.0\nopencensus-ext-stackdriver==0.8.0\nopencensus-ext-grpc==0.7.2\npython-json-logger==2.0.4\ngoogle-cloud-profiler==4.0.0\ngoogle-cloud-trace==0.24.2\nrequests==2.28.1\nprotobuf==3.20.1 # transitive dependency, move when google-api is bumped safely\npytest==7.1.3\n"
  },
  {
    "path": "microservices-demo/src/emailservice/requirements.txt",
    "content": "#\n# This file is autogenerated by pip-compile with python 3.10\n# To update, run:\n#\n#    pip-compile --output-file=requirements.txt requirements.in\n#\nattrs==22.1.0\n    # via pytest\ncachetools==5.2.0\n    # via google-auth\ncertifi==2022.6.15\n    # via requests\ncharset-normalizer==2.1.1\n    # via requests\ngoogle-api-core[grpc]==2.8.2\n    # via\n    #   -r requirements.in\n    #   google-api-python-client\n    #   google-cloud-core\n    #   google-cloud-monitoring\n    #   google-cloud-trace\n    #   opencensus\ngoogle-api-python-client==2.58.0\n    # via google-cloud-profiler\ngoogle-auth==2.11.0\n    # via\n    #   google-api-core\n    #   google-api-python-client\n    #   google-auth-httplib2\n    #   google-cloud-core\n    #   google-cloud-profiler\ngoogle-auth-httplib2==0.1.0\n    # via\n    #   google-api-python-client\n    #   google-cloud-profiler\ngoogle-cloud-core==2.3.2\n    # via google-cloud-trace\ngoogle-cloud-monitoring==2.11.1\n    # via opencensus-ext-stackdriver\ngoogle-cloud-profiler==4.0.0\n    # via -r requirements.in\ngoogle-cloud-trace==0.24.2\n    # via\n    #   -r requirements.in\n    #   opencensus-ext-stackdriver\ngoogleapis-common-protos==1.56.4\n    # via\n    #   google-api-core\n    #   grpcio-status\ngrpcio==1.47.0\n    # via\n    #   -r requirements.in\n    #   google-api-core\n    #   grpcio-health-checking\n    #   grpcio-status\n    #   opencensus-ext-grpc\ngrpcio-health-checking==1.47.0\n    # via -r requirements.in\ngrpcio-status==1.47.0\n    # via google-api-core\nhttplib2==0.20.4\n    # via\n    #   google-api-python-client\n    #   google-auth-httplib2\nidna==2.10\n    # via requests\niniconfig==1.1.1\n    # via pytest\njinja2==3.1.2\n    # via -r requirements.in\nmarkupsafe==2.1.1\n    # via jinja2\nopencensus==0.9.0\n    # via\n    #   -r requirements.in\n    #   opencensus-ext-grpc\n    #   opencensus-ext-stackdriver\nopencensus-context==0.1.3\n    # via opencensus\nopencensus-ext-grpc==0.7.2\n    # via -r requirements.in\nopencensus-ext-stackdriver==0.8.0\n    # via -r requirements.in\npackaging==21.3\n    # via pytest\npluggy==1.0.0\n    # via pytest\nproto-plus==1.22.1\n    # via google-cloud-monitoring\nprotobuf==3.20.1\n    # via\n    #   -r requirements.in\n    #   google-api-core\n    #   google-cloud-monitoring\n    #   google-cloud-profiler\n    #   google-cloud-trace\n    #   googleapis-common-protos\n    #   grpcio-health-checking\n    #   grpcio-status\n    #   proto-plus\npy==1.11.0\n    # via pytest\npyasn1==0.4.8\n    # via\n    #   pyasn1-modules\n    #   rsa\npyasn1-modules==0.2.8\n    # via google-auth\npyparsing==2.4.7\n    # via\n    #   httplib2\n    #   packaging\npytest==7.1.3\n    # via -r requirements.in\npython-json-logger==2.0.4\n    # via -r requirements.in\nrequests==2.28.1\n    # via\n    #   -r requirements.in\n    #   google-api-core\n    #   google-cloud-profiler\nrsa==4.8\n    # via google-auth\nsix==1.16.0\n    # via\n    #   google-auth\n    #   google-auth-httplib2\n    #   grpcio\ntomli==2.0.1\n    # via pytest\nuritemplate==3.0.1\n    # via google-api-python-client\nurllib3==1.26.12\n    # via requests\n"
  },
  {
    "path": "microservices-demo/src/emailservice/templates/confirmation.html",
    "content": "<!DOCTYPE html>\n<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n<html>\n  <head>\n    <title>Your Order Confirmation</title>\n    <link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap\" rel=\"stylesheet\">\n  </head>\n  <style>\n    body{\n      font-family: 'DM Sans', sans-serif;\n    }\n  </style>\n  <body>\n    <h2>Your Order Confirmation</h2>\n    <p>Thanks for shopping with us!<p>\n    <h3>Order ID</h3>\n    <p>#{{ order.order_id }}</p>\n    <h3>Shipping</h3>\n    <p>#{{ order.shipping_tracking_id }}</p>\n    <p>{{ order.shipping_cost.units }}. {{ \"%02d\" | format(order.shipping_cost.nanos // 10000000) }} {{ order.shipping_cost.currency_code }}</p>\n    <p>{{ order.shipping_address.street_address_1 }}, {{order.shipping_address.street_address_2}}, {{order.shipping_address.city}}, {{order.shipping_address.country}} {{order.shipping_address.zip_code}}</p>\n    <h3>Items</h3>\n    <table style=\"width:100%\">\n        <tr>\n          <th>Item No.</th>\n          <th>Quantity</th> \n          <th>Price</th>\n        </tr>\n        {% for item in order.items %}\n        <tr>\n          <td>#{{ item.item.product_id }}</td>\n          <td>{{ item.item.quantity }}</td> \n          <td>{{ item.cost.units }}.{{ \"%02d\" | format(item.cost.nanos // 10000000) }} {{ item.cost.currency_code }}</td>\n        </tr>\n        {% endfor %}\n    </table>\n  </body>\n</html>\n"
  },
  {
    "path": "microservices-demo/src/emailservice/tests/test_sample.py",
    "content": "def func(x):\n    return x + 1\n\n\ndef test_answer():\n    assert func(3) == 4\n"
  },
  {
    "path": "microservices-demo/src/frontend/.dockerignore",
    "content": "vendor/\n"
  },
  {
    "path": "microservices-demo/src/frontend/.gitkeep",
    "content": ""
  },
  {
    "path": "microservices-demo/src/frontend/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM golang:1.18.4-alpine as builder\nRUN apk add --no-cache ca-certificates git\nRUN apk add build-base\nWORKDIR /src\n\n# restore dependencies\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\n\n# Skaffold passes in debug-oriented compiler flags\nARG SKAFFOLD_GO_GCFLAGS\nRUN go build -gcflags=\"${SKAFFOLD_GO_GCFLAGS}\" -o /go/bin/frontend .\n\nFROM alpine as release\nRUN apk add --no-cache ca-certificates \\\n    busybox-extras net-tools bind-tools\nWORKDIR /src\nCOPY --from=builder /go/bin/frontend /src/server\nCOPY ./templates ./templates\nCOPY ./static ./static\n\n# Definition of this variable is used by 'skaffold debug' to identify a golang binary.\n# Default behavior - a failure prints a stack trace for the current goroutine.\n# See https://golang.org/pkg/runtime/\nENV GOTRACEBACK=single\n\nEXPOSE 8080\nENTRYPOINT [\"/src/server\"]\n"
  },
  {
    "path": "microservices-demo/src/frontend/README.md",
    "content": "# frontend\n\nRun the following command to restore dependencies to `vendor/` directory:\n\n    dep ensure --vendor-only\n"
  },
  {
    "path": "microservices-demo/src/frontend/deployment_details.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"cloud.google.com/go/compute/metadata\"\n\t\"github.com/sirupsen/logrus\"\n)\n\nvar deploymentDetailsMap map[string]string\nvar log *logrus.Logger\n\nfunc init() {\n\tinitializeLogger()\n\t// Use a goroutine to ensure loadDeploymentDetails()'s GCP API\n\t// calls don't block non-GCP deployments. See issue #685.\n\tgo loadDeploymentDetails()\n}\n\nfunc initializeLogger() {\n\tlog = logrus.New()\n\tlog.Level = logrus.DebugLevel\n\tlog.Formatter = &logrus.JSONFormatter{\n\t\tFieldMap: logrus.FieldMap{\n\t\t\tlogrus.FieldKeyTime:  \"timestamp\",\n\t\t\tlogrus.FieldKeyLevel: \"severity\",\n\t\t\tlogrus.FieldKeyMsg:   \"message\",\n\t\t},\n\t\tTimestampFormat: time.RFC3339Nano,\n\t}\n\tlog.Out = os.Stdout\n}\n\nfunc loadDeploymentDetails() {\n\tdeploymentDetailsMap = make(map[string]string)\n\tvar metaServerClient = metadata.NewClient(&http.Client{})\n\n\tpodHostname, err := os.Hostname()\n\tif err != nil {\n\t\tlog.Error(\"Failed to fetch the hostname for the Pod\", err)\n\t}\n\n\tpodCluster, err := metaServerClient.InstanceAttributeValue(\"cluster-name\")\n\tif err != nil {\n\t\tlog.Error(\"Failed to fetch the name of the cluster in which the pod is running\", err)\n\t}\n\n\tpodZone, err := metaServerClient.Zone()\n\tif err != nil {\n\t\tlog.Error(\"Failed to fetch the Zone of the node where the pod is scheduled\", err)\n\t}\n\n\tdeploymentDetailsMap[\"HOSTNAME\"] = podHostname\n\tdeploymentDetailsMap[\"CLUSTERNAME\"] = podCluster\n\tdeploymentDetailsMap[\"ZONE\"] = podZone\n\n\tlog.WithFields(logrus.Fields{\n\t\t\"cluster\":  podCluster,\n\t\t\"zone\":     podZone,\n\t\t\"hostname\": podHostname,\n\t}).Debug(\"Loaded deployment details\")\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/genproto/demo.pb.go",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: demo.proto\n\npackage hipstershop\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.com/golang/protobuf/proto\"\n\tmath \"math\"\n)\n\nimport (\n\tcontext \"golang.org/x/net/context\"\n\tgrpc \"google.golang.org/grpc\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype CartItem struct {\n\tProductId            string   `protobuf:\"bytes,1,opt,name=product_id,json=productId,proto3\" json:\"product_id,omitempty\"`\n\tQuantity             int32    `protobuf:\"varint,2,opt,name=quantity,proto3\" json:\"quantity,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CartItem) Reset()         { *m = CartItem{} }\nfunc (m *CartItem) String() string { return proto.CompactTextString(m) }\nfunc (*CartItem) ProtoMessage()    {}\nfunc (*CartItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{0}\n}\n\nfunc (m *CartItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CartItem.Unmarshal(m, b)\n}\nfunc (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CartItem.Marshal(b, m, deterministic)\n}\nfunc (m *CartItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CartItem.Merge(m, src)\n}\nfunc (m *CartItem) XXX_Size() int {\n\treturn xxx_messageInfo_CartItem.Size(m)\n}\nfunc (m *CartItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_CartItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CartItem proto.InternalMessageInfo\n\nfunc (m *CartItem) GetProductId() string {\n\tif m != nil {\n\t\treturn m.ProductId\n\t}\n\treturn \"\"\n}\n\nfunc (m *CartItem) GetQuantity() int32 {\n\tif m != nil {\n\t\treturn m.Quantity\n\t}\n\treturn 0\n}\n\ntype AddItemRequest struct {\n\tUserId               string    `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItem                 *CartItem `protobuf:\"bytes,2,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *AddItemRequest) Reset()         { *m = AddItemRequest{} }\nfunc (m *AddItemRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AddItemRequest) ProtoMessage()    {}\nfunc (*AddItemRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{1}\n}\n\nfunc (m *AddItemRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AddItemRequest.Unmarshal(m, b)\n}\nfunc (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AddItemRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AddItemRequest.Merge(m, src)\n}\nfunc (m *AddItemRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AddItemRequest.Size(m)\n}\nfunc (m *AddItemRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AddItemRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AddItemRequest proto.InternalMessageInfo\n\nfunc (m *AddItemRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *AddItemRequest) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\ntype EmptyCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *EmptyCartRequest) Reset()         { *m = EmptyCartRequest{} }\nfunc (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*EmptyCartRequest) ProtoMessage()    {}\nfunc (*EmptyCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{2}\n}\n\nfunc (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)\n}\nfunc (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *EmptyCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_EmptyCartRequest.Merge(m, src)\n}\nfunc (m *EmptyCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_EmptyCartRequest.Size(m)\n}\nfunc (m *EmptyCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_EmptyCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo\n\nfunc (m *EmptyCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype GetCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetCartRequest) Reset()         { *m = GetCartRequest{} }\nfunc (m *GetCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetCartRequest) ProtoMessage()    {}\nfunc (*GetCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{3}\n}\n\nfunc (m *GetCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetCartRequest.Unmarshal(m, b)\n}\nfunc (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetCartRequest.Merge(m, src)\n}\nfunc (m *GetCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetCartRequest.Size(m)\n}\nfunc (m *GetCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetCartRequest proto.InternalMessageInfo\n\nfunc (m *GetCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype Cart struct {\n\tUserId               string      `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *Cart) Reset()         { *m = Cart{} }\nfunc (m *Cart) String() string { return proto.CompactTextString(m) }\nfunc (*Cart) ProtoMessage()    {}\nfunc (*Cart) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{4}\n}\n\nfunc (m *Cart) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Cart.Unmarshal(m, b)\n}\nfunc (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Cart.Marshal(b, m, deterministic)\n}\nfunc (m *Cart) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Cart.Merge(m, src)\n}\nfunc (m *Cart) XXX_Size() int {\n\treturn xxx_messageInfo_Cart.Size(m)\n}\nfunc (m *Cart) XXX_DiscardUnknown() {\n\txxx_messageInfo_Cart.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Cart proto.InternalMessageInfo\n\nfunc (m *Cart) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *Cart) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype Empty struct {\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Empty) Reset()         { *m = Empty{} }\nfunc (m *Empty) String() string { return proto.CompactTextString(m) }\nfunc (*Empty) ProtoMessage()    {}\nfunc (*Empty) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{5}\n}\n\nfunc (m *Empty) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Empty.Unmarshal(m, b)\n}\nfunc (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Empty.Marshal(b, m, deterministic)\n}\nfunc (m *Empty) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Empty.Merge(m, src)\n}\nfunc (m *Empty) XXX_Size() int {\n\treturn xxx_messageInfo_Empty.Size(m)\n}\nfunc (m *Empty) XXX_DiscardUnknown() {\n\txxx_messageInfo_Empty.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Empty proto.InternalMessageInfo\n\ntype ListRecommendationsRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tProductIds           []string `protobuf:\"bytes,2,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsRequest) Reset()         { *m = ListRecommendationsRequest{} }\nfunc (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsRequest) ProtoMessage()    {}\nfunc (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{6}\n}\n\nfunc (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsRequest.Merge(m, src)\n}\nfunc (m *ListRecommendationsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Size(m)\n}\nfunc (m *ListRecommendationsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *ListRecommendationsRequest) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype ListRecommendationsResponse struct {\n\tProductIds           []string `protobuf:\"bytes,1,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsResponse) Reset()         { *m = ListRecommendationsResponse{} }\nfunc (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsResponse) ProtoMessage()    {}\nfunc (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{7}\n}\n\nfunc (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsResponse.Merge(m, src)\n}\nfunc (m *ListRecommendationsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Size(m)\n}\nfunc (m *ListRecommendationsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsResponse) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype Product struct {\n\tId          string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName        string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tPicture     string `protobuf:\"bytes,4,opt,name=picture,proto3\" json:\"picture,omitempty\"`\n\tPriceUsd    *Money `protobuf:\"bytes,5,opt,name=price_usd,json=priceUsd,proto3\" json:\"price_usd,omitempty\"`\n\t// Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n\t// other related products.\n\tCategories           []string `protobuf:\"bytes,6,rep,name=categories,proto3\" json:\"categories,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Product) Reset()         { *m = Product{} }\nfunc (m *Product) String() string { return proto.CompactTextString(m) }\nfunc (*Product) ProtoMessage()    {}\nfunc (*Product) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{8}\n}\n\nfunc (m *Product) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Product.Unmarshal(m, b)\n}\nfunc (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Product.Marshal(b, m, deterministic)\n}\nfunc (m *Product) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Product.Merge(m, src)\n}\nfunc (m *Product) XXX_Size() int {\n\treturn xxx_messageInfo_Product.Size(m)\n}\nfunc (m *Product) XXX_DiscardUnknown() {\n\txxx_messageInfo_Product.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Product proto.InternalMessageInfo\n\nfunc (m *Product) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetDescription() string {\n\tif m != nil {\n\t\treturn m.Description\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPicture() string {\n\tif m != nil {\n\t\treturn m.Picture\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPriceUsd() *Money {\n\tif m != nil {\n\t\treturn m.PriceUsd\n\t}\n\treturn nil\n}\n\nfunc (m *Product) GetCategories() []string {\n\tif m != nil {\n\t\treturn m.Categories\n\t}\n\treturn nil\n}\n\ntype ListProductsResponse struct {\n\tProducts             []*Product `protobuf:\"bytes,1,rep,name=products,proto3\" json:\"products,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *ListProductsResponse) Reset()         { *m = ListProductsResponse{} }\nfunc (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListProductsResponse) ProtoMessage()    {}\nfunc (*ListProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{9}\n}\n\nfunc (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)\n}\nfunc (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListProductsResponse.Merge(m, src)\n}\nfunc (m *ListProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListProductsResponse.Size(m)\n}\nfunc (m *ListProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo\n\nfunc (m *ListProductsResponse) GetProducts() []*Product {\n\tif m != nil {\n\t\treturn m.Products\n\t}\n\treturn nil\n}\n\ntype GetProductRequest struct {\n\tId                   string   `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetProductRequest) Reset()         { *m = GetProductRequest{} }\nfunc (m *GetProductRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetProductRequest) ProtoMessage()    {}\nfunc (*GetProductRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{10}\n}\n\nfunc (m *GetProductRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetProductRequest.Unmarshal(m, b)\n}\nfunc (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetProductRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetProductRequest.Merge(m, src)\n}\nfunc (m *GetProductRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetProductRequest.Size(m)\n}\nfunc (m *GetProductRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetProductRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetProductRequest proto.InternalMessageInfo\n\nfunc (m *GetProductRequest) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsRequest struct {\n\tQuery                string   `protobuf:\"bytes,1,opt,name=query,proto3\" json:\"query,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *SearchProductsRequest) Reset()         { *m = SearchProductsRequest{} }\nfunc (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsRequest) ProtoMessage()    {}\nfunc (*SearchProductsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{11}\n}\n\nfunc (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)\n}\nfunc (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsRequest.Merge(m, src)\n}\nfunc (m *SearchProductsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsRequest.Size(m)\n}\nfunc (m *SearchProductsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo\n\nfunc (m *SearchProductsRequest) GetQuery() string {\n\tif m != nil {\n\t\treturn m.Query\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsResponse struct {\n\tResults              []*Product `protobuf:\"bytes,1,rep,name=results,proto3\" json:\"results,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *SearchProductsResponse) Reset()         { *m = SearchProductsResponse{} }\nfunc (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsResponse) ProtoMessage()    {}\nfunc (*SearchProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{12}\n}\n\nfunc (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)\n}\nfunc (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsResponse.Merge(m, src)\n}\nfunc (m *SearchProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsResponse.Size(m)\n}\nfunc (m *SearchProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo\n\nfunc (m *SearchProductsResponse) GetResults() []*Product {\n\tif m != nil {\n\t\treturn m.Results\n\t}\n\treturn nil\n}\n\ntype GetQuoteRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *GetQuoteRequest) Reset()         { *m = GetQuoteRequest{} }\nfunc (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteRequest) ProtoMessage()    {}\nfunc (*GetQuoteRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{13}\n}\n\nfunc (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)\n}\nfunc (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteRequest.Merge(m, src)\n}\nfunc (m *GetQuoteRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteRequest.Size(m)\n}\nfunc (m *GetQuoteRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo\n\nfunc (m *GetQuoteRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *GetQuoteRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype GetQuoteResponse struct {\n\tCostUsd              *Money   `protobuf:\"bytes,1,opt,name=cost_usd,json=costUsd,proto3\" json:\"cost_usd,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetQuoteResponse) Reset()         { *m = GetQuoteResponse{} }\nfunc (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteResponse) ProtoMessage()    {}\nfunc (*GetQuoteResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{14}\n}\n\nfunc (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)\n}\nfunc (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteResponse.Merge(m, src)\n}\nfunc (m *GetQuoteResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteResponse.Size(m)\n}\nfunc (m *GetQuoteResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo\n\nfunc (m *GetQuoteResponse) GetCostUsd() *Money {\n\tif m != nil {\n\t\treturn m.CostUsd\n\t}\n\treturn nil\n}\n\ntype ShipOrderRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *ShipOrderRequest) Reset()         { *m = ShipOrderRequest{} }\nfunc (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderRequest) ProtoMessage()    {}\nfunc (*ShipOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{15}\n}\n\nfunc (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)\n}\nfunc (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderRequest.Merge(m, src)\n}\nfunc (m *ShipOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderRequest.Size(m)\n}\nfunc (m *ShipOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo\n\nfunc (m *ShipOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *ShipOrderRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype ShipOrderResponse struct {\n\tTrackingId           string   `protobuf:\"bytes,1,opt,name=tracking_id,json=trackingId,proto3\" json:\"tracking_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ShipOrderResponse) Reset()         { *m = ShipOrderResponse{} }\nfunc (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderResponse) ProtoMessage()    {}\nfunc (*ShipOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{16}\n}\n\nfunc (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)\n}\nfunc (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderResponse.Merge(m, src)\n}\nfunc (m *ShipOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderResponse.Size(m)\n}\nfunc (m *ShipOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo\n\nfunc (m *ShipOrderResponse) GetTrackingId() string {\n\tif m != nil {\n\t\treturn m.TrackingId\n\t}\n\treturn \"\"\n}\n\ntype Address struct {\n\tStreetAddress        string   `protobuf:\"bytes,1,opt,name=street_address,json=streetAddress,proto3\" json:\"street_address,omitempty\"`\n\tCity                 string   `protobuf:\"bytes,2,opt,name=city,proto3\" json:\"city,omitempty\"`\n\tState                string   `protobuf:\"bytes,3,opt,name=state,proto3\" json:\"state,omitempty\"`\n\tCountry              string   `protobuf:\"bytes,4,opt,name=country,proto3\" json:\"country,omitempty\"`\n\tZipCode              int32    `protobuf:\"varint,5,opt,name=zip_code,json=zipCode,proto3\" json:\"zip_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Address) Reset()         { *m = Address{} }\nfunc (m *Address) String() string { return proto.CompactTextString(m) }\nfunc (*Address) ProtoMessage()    {}\nfunc (*Address) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{17}\n}\n\nfunc (m *Address) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Address.Unmarshal(m, b)\n}\nfunc (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Address.Marshal(b, m, deterministic)\n}\nfunc (m *Address) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Address.Merge(m, src)\n}\nfunc (m *Address) XXX_Size() int {\n\treturn xxx_messageInfo_Address.Size(m)\n}\nfunc (m *Address) XXX_DiscardUnknown() {\n\txxx_messageInfo_Address.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Address proto.InternalMessageInfo\n\nfunc (m *Address) GetStreetAddress() string {\n\tif m != nil {\n\t\treturn m.StreetAddress\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCity() string {\n\tif m != nil {\n\t\treturn m.City\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetState() string {\n\tif m != nil {\n\t\treturn m.State\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCountry() string {\n\tif m != nil {\n\t\treturn m.Country\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetZipCode() int32 {\n\tif m != nil {\n\t\treturn m.ZipCode\n\t}\n\treturn 0\n}\n\n// Represents an amount of money with its currency type.\ntype Money struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCode string `protobuf:\"bytes,1,opt,name=currency_code,json=currencyCode,proto3\" json:\"currency_code,omitempty\"`\n\t// The whole units of the amount.\n\t// For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n\tUnits int64 `protobuf:\"varint,2,opt,name=units,proto3\" json:\"units,omitempty\"`\n\t// Number of nano (10^-9) units of the amount.\n\t// The value must be between -999,999,999 and +999,999,999 inclusive.\n\t// If `units` is positive, `nanos` must be positive or zero.\n\t// If `units` is zero, `nanos` can be positive, zero, or negative.\n\t// If `units` is negative, `nanos` must be negative or zero.\n\t// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n\tNanos                int32    `protobuf:\"varint,3,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Money) Reset()         { *m = Money{} }\nfunc (m *Money) String() string { return proto.CompactTextString(m) }\nfunc (*Money) ProtoMessage()    {}\nfunc (*Money) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{18}\n}\n\nfunc (m *Money) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Money.Unmarshal(m, b)\n}\nfunc (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Money.Marshal(b, m, deterministic)\n}\nfunc (m *Money) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Money.Merge(m, src)\n}\nfunc (m *Money) XXX_Size() int {\n\treturn xxx_messageInfo_Money.Size(m)\n}\nfunc (m *Money) XXX_DiscardUnknown() {\n\txxx_messageInfo_Money.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Money proto.InternalMessageInfo\n\nfunc (m *Money) GetCurrencyCode() string {\n\tif m != nil {\n\t\treturn m.CurrencyCode\n\t}\n\treturn \"\"\n}\n\nfunc (m *Money) GetUnits() int64 {\n\tif m != nil {\n\t\treturn m.Units\n\t}\n\treturn 0\n}\n\nfunc (m *Money) GetNanos() int32 {\n\tif m != nil {\n\t\treturn m.Nanos\n\t}\n\treturn 0\n}\n\ntype GetSupportedCurrenciesResponse struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCodes        []string `protobuf:\"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3\" json:\"currency_codes,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetSupportedCurrenciesResponse) Reset()         { *m = GetSupportedCurrenciesResponse{} }\nfunc (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetSupportedCurrenciesResponse) ProtoMessage()    {}\nfunc (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{19}\n}\n\nfunc (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo\n\nfunc (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string {\n\tif m != nil {\n\t\treturn m.CurrencyCodes\n\t}\n\treturn nil\n}\n\ntype CurrencyConversionRequest struct {\n\tFrom *Money `protobuf:\"bytes,1,opt,name=from,proto3\" json:\"from,omitempty\"`\n\t// The 3-letter currency code defined in ISO 4217.\n\tToCode               string   `protobuf:\"bytes,2,opt,name=to_code,json=toCode,proto3\" json:\"to_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CurrencyConversionRequest) Reset()         { *m = CurrencyConversionRequest{} }\nfunc (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }\nfunc (*CurrencyConversionRequest) ProtoMessage()    {}\nfunc (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{20}\n}\n\nfunc (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)\n}\nfunc (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)\n}\nfunc (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CurrencyConversionRequest.Merge(m, src)\n}\nfunc (m *CurrencyConversionRequest) XXX_Size() int {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Size(m)\n}\nfunc (m *CurrencyConversionRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo\n\nfunc (m *CurrencyConversionRequest) GetFrom() *Money {\n\tif m != nil {\n\t\treturn m.From\n\t}\n\treturn nil\n}\n\nfunc (m *CurrencyConversionRequest) GetToCode() string {\n\tif m != nil {\n\t\treturn m.ToCode\n\t}\n\treturn \"\"\n}\n\ntype CreditCardInfo struct {\n\tCreditCardNumber          string   `protobuf:\"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3\" json:\"credit_card_number,omitempty\"`\n\tCreditCardCvv             int32    `protobuf:\"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3\" json:\"credit_card_cvv,omitempty\"`\n\tCreditCardExpirationYear  int32    `protobuf:\"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3\" json:\"credit_card_expiration_year,omitempty\"`\n\tCreditCardExpirationMonth int32    `protobuf:\"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3\" json:\"credit_card_expiration_month,omitempty\"`\n\tXXX_NoUnkeyedLiteral      struct{} `json:\"-\"`\n\tXXX_unrecognized          []byte   `json:\"-\"`\n\tXXX_sizecache             int32    `json:\"-\"`\n}\n\nfunc (m *CreditCardInfo) Reset()         { *m = CreditCardInfo{} }\nfunc (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }\nfunc (*CreditCardInfo) ProtoMessage()    {}\nfunc (*CreditCardInfo) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{21}\n}\n\nfunc (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)\n}\nfunc (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)\n}\nfunc (m *CreditCardInfo) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CreditCardInfo.Merge(m, src)\n}\nfunc (m *CreditCardInfo) XXX_Size() int {\n\treturn xxx_messageInfo_CreditCardInfo.Size(m)\n}\nfunc (m *CreditCardInfo) XXX_DiscardUnknown() {\n\txxx_messageInfo_CreditCardInfo.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo\n\nfunc (m *CreditCardInfo) GetCreditCardNumber() string {\n\tif m != nil {\n\t\treturn m.CreditCardNumber\n\t}\n\treturn \"\"\n}\n\nfunc (m *CreditCardInfo) GetCreditCardCvv() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardCvv\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationYear() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationYear\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationMonth\n\t}\n\treturn 0\n}\n\ntype ChargeRequest struct {\n\tAmount               *Money          `protobuf:\"bytes,1,opt,name=amount,proto3\" json:\"amount,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,2,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *ChargeRequest) Reset()         { *m = ChargeRequest{} }\nfunc (m *ChargeRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeRequest) ProtoMessage()    {}\nfunc (*ChargeRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{22}\n}\n\nfunc (m *ChargeRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeRequest.Unmarshal(m, b)\n}\nfunc (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeRequest.Merge(m, src)\n}\nfunc (m *ChargeRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeRequest.Size(m)\n}\nfunc (m *ChargeRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeRequest proto.InternalMessageInfo\n\nfunc (m *ChargeRequest) GetAmount() *Money {\n\tif m != nil {\n\t\treturn m.Amount\n\t}\n\treturn nil\n}\n\nfunc (m *ChargeRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype ChargeResponse struct {\n\tTransactionId        string   `protobuf:\"bytes,1,opt,name=transaction_id,json=transactionId,proto3\" json:\"transaction_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ChargeResponse) Reset()         { *m = ChargeResponse{} }\nfunc (m *ChargeResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeResponse) ProtoMessage()    {}\nfunc (*ChargeResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{23}\n}\n\nfunc (m *ChargeResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeResponse.Unmarshal(m, b)\n}\nfunc (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeResponse.Merge(m, src)\n}\nfunc (m *ChargeResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeResponse.Size(m)\n}\nfunc (m *ChargeResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeResponse proto.InternalMessageInfo\n\nfunc (m *ChargeResponse) GetTransactionId() string {\n\tif m != nil {\n\t\treturn m.TransactionId\n\t}\n\treturn \"\"\n}\n\ntype OrderItem struct {\n\tItem                 *CartItem `protobuf:\"bytes,1,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tCost                 *Money    `protobuf:\"bytes,2,opt,name=cost,proto3\" json:\"cost,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *OrderItem) Reset()         { *m = OrderItem{} }\nfunc (m *OrderItem) String() string { return proto.CompactTextString(m) }\nfunc (*OrderItem) ProtoMessage()    {}\nfunc (*OrderItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{24}\n}\n\nfunc (m *OrderItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderItem.Unmarshal(m, b)\n}\nfunc (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)\n}\nfunc (m *OrderItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderItem.Merge(m, src)\n}\nfunc (m *OrderItem) XXX_Size() int {\n\treturn xxx_messageInfo_OrderItem.Size(m)\n}\nfunc (m *OrderItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderItem proto.InternalMessageInfo\n\nfunc (m *OrderItem) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\nfunc (m *OrderItem) GetCost() *Money {\n\tif m != nil {\n\t\treturn m.Cost\n\t}\n\treturn nil\n}\n\ntype OrderResult struct {\n\tOrderId              string       `protobuf:\"bytes,1,opt,name=order_id,json=orderId,proto3\" json:\"order_id,omitempty\"`\n\tShippingTrackingId   string       `protobuf:\"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3\" json:\"shipping_tracking_id,omitempty\"`\n\tShippingCost         *Money       `protobuf:\"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3\" json:\"shipping_cost,omitempty\"`\n\tShippingAddress      *Address     `protobuf:\"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3\" json:\"shipping_address,omitempty\"`\n\tItems                []*OrderItem `protobuf:\"bytes,5,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *OrderResult) Reset()         { *m = OrderResult{} }\nfunc (m *OrderResult) String() string { return proto.CompactTextString(m) }\nfunc (*OrderResult) ProtoMessage()    {}\nfunc (*OrderResult) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{25}\n}\n\nfunc (m *OrderResult) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderResult.Unmarshal(m, b)\n}\nfunc (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)\n}\nfunc (m *OrderResult) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderResult.Merge(m, src)\n}\nfunc (m *OrderResult) XXX_Size() int {\n\treturn xxx_messageInfo_OrderResult.Size(m)\n}\nfunc (m *OrderResult) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderResult.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderResult proto.InternalMessageInfo\n\nfunc (m *OrderResult) GetOrderId() string {\n\tif m != nil {\n\t\treturn m.OrderId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingTrackingId() string {\n\tif m != nil {\n\t\treturn m.ShippingTrackingId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingCost() *Money {\n\tif m != nil {\n\t\treturn m.ShippingCost\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetShippingAddress() *Address {\n\tif m != nil {\n\t\treturn m.ShippingAddress\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetItems() []*OrderItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype SendOrderConfirmationRequest struct {\n\tEmail                string       `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tOrder                *OrderResult `protobuf:\"bytes,2,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *SendOrderConfirmationRequest) Reset()         { *m = SendOrderConfirmationRequest{} }\nfunc (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SendOrderConfirmationRequest) ProtoMessage()    {}\nfunc (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{26}\n}\n\nfunc (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Size(m)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo\n\nfunc (m *SendOrderConfirmationRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *SendOrderConfirmationRequest) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype PlaceOrderRequest struct {\n\tUserId               string          `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tUserCurrency         string          `protobuf:\"bytes,2,opt,name=user_currency,json=userCurrency,proto3\" json:\"user_currency,omitempty\"`\n\tAddress              *Address        `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tEmail                string          `protobuf:\"bytes,5,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,6,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *PlaceOrderRequest) Reset()         { *m = PlaceOrderRequest{} }\nfunc (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderRequest) ProtoMessage()    {}\nfunc (*PlaceOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{27}\n}\n\nfunc (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderRequest.Merge(m, src)\n}\nfunc (m *PlaceOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderRequest.Size(m)\n}\nfunc (m *PlaceOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo\n\nfunc (m *PlaceOrderRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetUserCurrency() string {\n\tif m != nil {\n\t\treturn m.UserCurrency\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *PlaceOrderRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype PlaceOrderResponse struct {\n\tOrder                *OrderResult `protobuf:\"bytes,1,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *PlaceOrderResponse) Reset()         { *m = PlaceOrderResponse{} }\nfunc (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderResponse) ProtoMessage()    {}\nfunc (*PlaceOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{28}\n}\n\nfunc (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderResponse.Merge(m, src)\n}\nfunc (m *PlaceOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderResponse.Size(m)\n}\nfunc (m *PlaceOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo\n\nfunc (m *PlaceOrderResponse) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype AdRequest struct {\n\t// List of important key words from the current page describing the context.\n\tContextKeys          []string `protobuf:\"bytes,1,rep,name=context_keys,json=contextKeys,proto3\" json:\"context_keys,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdRequest) Reset()         { *m = AdRequest{} }\nfunc (m *AdRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AdRequest) ProtoMessage()    {}\nfunc (*AdRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{29}\n}\n\nfunc (m *AdRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdRequest.Unmarshal(m, b)\n}\nfunc (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AdRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdRequest.Merge(m, src)\n}\nfunc (m *AdRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AdRequest.Size(m)\n}\nfunc (m *AdRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdRequest proto.InternalMessageInfo\n\nfunc (m *AdRequest) GetContextKeys() []string {\n\tif m != nil {\n\t\treturn m.ContextKeys\n\t}\n\treturn nil\n}\n\ntype AdResponse struct {\n\tAds                  []*Ad    `protobuf:\"bytes,1,rep,name=ads,proto3\" json:\"ads,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdResponse) Reset()         { *m = AdResponse{} }\nfunc (m *AdResponse) String() string { return proto.CompactTextString(m) }\nfunc (*AdResponse) ProtoMessage()    {}\nfunc (*AdResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{30}\n}\n\nfunc (m *AdResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdResponse.Unmarshal(m, b)\n}\nfunc (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)\n}\nfunc (m *AdResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdResponse.Merge(m, src)\n}\nfunc (m *AdResponse) XXX_Size() int {\n\treturn xxx_messageInfo_AdResponse.Size(m)\n}\nfunc (m *AdResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdResponse proto.InternalMessageInfo\n\nfunc (m *AdResponse) GetAds() []*Ad {\n\tif m != nil {\n\t\treturn m.Ads\n\t}\n\treturn nil\n}\n\ntype Ad struct {\n\t// url to redirect to when an ad is clicked.\n\tRedirectUrl string `protobuf:\"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3\" json:\"redirect_url,omitempty\"`\n\t// short advertisement text to display.\n\tText                 string   `protobuf:\"bytes,2,opt,name=text,proto3\" json:\"text,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Ad) Reset()         { *m = Ad{} }\nfunc (m *Ad) String() string { return proto.CompactTextString(m) }\nfunc (*Ad) ProtoMessage()    {}\nfunc (*Ad) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{31}\n}\n\nfunc (m *Ad) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Ad.Unmarshal(m, b)\n}\nfunc (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Ad.Marshal(b, m, deterministic)\n}\nfunc (m *Ad) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Ad.Merge(m, src)\n}\nfunc (m *Ad) XXX_Size() int {\n\treturn xxx_messageInfo_Ad.Size(m)\n}\nfunc (m *Ad) XXX_DiscardUnknown() {\n\txxx_messageInfo_Ad.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Ad proto.InternalMessageInfo\n\nfunc (m *Ad) GetRedirectUrl() string {\n\tif m != nil {\n\t\treturn m.RedirectUrl\n\t}\n\treturn \"\"\n}\n\nfunc (m *Ad) GetText() string {\n\tif m != nil {\n\t\treturn m.Text\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*CartItem)(nil), \"hipstershop.CartItem\")\n\tproto.RegisterType((*AddItemRequest)(nil), \"hipstershop.AddItemRequest\")\n\tproto.RegisterType((*EmptyCartRequest)(nil), \"hipstershop.EmptyCartRequest\")\n\tproto.RegisterType((*GetCartRequest)(nil), \"hipstershop.GetCartRequest\")\n\tproto.RegisterType((*Cart)(nil), \"hipstershop.Cart\")\n\tproto.RegisterType((*Empty)(nil), \"hipstershop.Empty\")\n\tproto.RegisterType((*ListRecommendationsRequest)(nil), \"hipstershop.ListRecommendationsRequest\")\n\tproto.RegisterType((*ListRecommendationsResponse)(nil), \"hipstershop.ListRecommendationsResponse\")\n\tproto.RegisterType((*Product)(nil), \"hipstershop.Product\")\n\tproto.RegisterType((*ListProductsResponse)(nil), \"hipstershop.ListProductsResponse\")\n\tproto.RegisterType((*GetProductRequest)(nil), \"hipstershop.GetProductRequest\")\n\tproto.RegisterType((*SearchProductsRequest)(nil), \"hipstershop.SearchProductsRequest\")\n\tproto.RegisterType((*SearchProductsResponse)(nil), \"hipstershop.SearchProductsResponse\")\n\tproto.RegisterType((*GetQuoteRequest)(nil), \"hipstershop.GetQuoteRequest\")\n\tproto.RegisterType((*GetQuoteResponse)(nil), \"hipstershop.GetQuoteResponse\")\n\tproto.RegisterType((*ShipOrderRequest)(nil), \"hipstershop.ShipOrderRequest\")\n\tproto.RegisterType((*ShipOrderResponse)(nil), \"hipstershop.ShipOrderResponse\")\n\tproto.RegisterType((*Address)(nil), \"hipstershop.Address\")\n\tproto.RegisterType((*Money)(nil), \"hipstershop.Money\")\n\tproto.RegisterType((*GetSupportedCurrenciesResponse)(nil), \"hipstershop.GetSupportedCurrenciesResponse\")\n\tproto.RegisterType((*CurrencyConversionRequest)(nil), \"hipstershop.CurrencyConversionRequest\")\n\tproto.RegisterType((*CreditCardInfo)(nil), \"hipstershop.CreditCardInfo\")\n\tproto.RegisterType((*ChargeRequest)(nil), \"hipstershop.ChargeRequest\")\n\tproto.RegisterType((*ChargeResponse)(nil), \"hipstershop.ChargeResponse\")\n\tproto.RegisterType((*OrderItem)(nil), \"hipstershop.OrderItem\")\n\tproto.RegisterType((*OrderResult)(nil), \"hipstershop.OrderResult\")\n\tproto.RegisterType((*SendOrderConfirmationRequest)(nil), \"hipstershop.SendOrderConfirmationRequest\")\n\tproto.RegisterType((*PlaceOrderRequest)(nil), \"hipstershop.PlaceOrderRequest\")\n\tproto.RegisterType((*PlaceOrderResponse)(nil), \"hipstershop.PlaceOrderResponse\")\n\tproto.RegisterType((*AdRequest)(nil), \"hipstershop.AdRequest\")\n\tproto.RegisterType((*AdResponse)(nil), \"hipstershop.AdResponse\")\n\tproto.RegisterType((*Ad)(nil), \"hipstershop.Ad\")\n}\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ context.Context\nvar _ grpc.ClientConn\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\nconst _ = grpc.SupportPackageIsVersion4\n\n// CartServiceClient is the client API for CartService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CartServiceClient interface {\n\tAddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error)\n\tGetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error)\n\tEmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype cartServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient {\n\treturn &cartServiceClient{cc}\n}\n\nfunc (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/AddItem\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) {\n\tout := new(Cart)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/GetCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/EmptyCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CartServiceServer is the server API for CartService service.\ntype CartServiceServer interface {\n\tAddItem(context.Context, *AddItemRequest) (*Empty, error)\n\tGetCart(context.Context, *GetCartRequest) (*Cart, error)\n\tEmptyCart(context.Context, *EmptyCartRequest) (*Empty, error)\n}\n\nfunc RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) {\n\ts.RegisterService(&_CartService_serviceDesc, srv)\n}\n\nfunc _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddItemRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/AddItem\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/GetCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(EmptyCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/EmptyCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CartService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CartService\",\n\tHandlerType: (*CartServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"AddItem\",\n\t\t\tHandler:    _CartService_AddItem_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetCart\",\n\t\t\tHandler:    _CartService_GetCart_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"EmptyCart\",\n\t\t\tHandler:    _CartService_EmptyCart_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// RecommendationServiceClient is the client API for RecommendationService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype RecommendationServiceClient interface {\n\tListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error)\n}\n\ntype recommendationServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {\n\treturn &recommendationServiceClient{cc}\n}\n\nfunc (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) {\n\tout := new(ListRecommendationsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.RecommendationService/ListRecommendations\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// RecommendationServiceServer is the server API for RecommendationService service.\ntype RecommendationServiceServer interface {\n\tListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error)\n}\n\nfunc RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {\n\ts.RegisterService(&_RecommendationService_serviceDesc, srv)\n}\n\nfunc _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListRecommendationsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.RecommendationService/ListRecommendations\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _RecommendationService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.RecommendationService\",\n\tHandlerType: (*RecommendationServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListRecommendations\",\n\t\t\tHandler:    _RecommendationService_ListRecommendations_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ProductCatalogServiceClient is the client API for ProductCatalogService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ProductCatalogServiceClient interface {\n\tListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error)\n\tGetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error)\n\tSearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error)\n}\n\ntype productCatalogServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient {\n\treturn &productCatalogServiceClient{cc}\n}\n\nfunc (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) {\n\tout := new(ListProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/ListProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) {\n\tout := new(Product)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/GetProduct\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) {\n\tout := new(SearchProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/SearchProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ProductCatalogServiceServer is the server API for ProductCatalogService service.\ntype ProductCatalogServiceServer interface {\n\tListProducts(context.Context, *Empty) (*ListProductsResponse, error)\n\tGetProduct(context.Context, *GetProductRequest) (*Product, error)\n\tSearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error)\n}\n\nfunc RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) {\n\ts.RegisterService(&_ProductCatalogService_serviceDesc, srv)\n}\n\nfunc _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/ListProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetProductRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/GetProduct\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SearchProductsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/SearchProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ProductCatalogService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ProductCatalogService\",\n\tHandlerType: (*ProductCatalogServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListProducts\",\n\t\t\tHandler:    _ProductCatalogService_ListProducts_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetProduct\",\n\t\t\tHandler:    _ProductCatalogService_GetProduct_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"SearchProducts\",\n\t\t\tHandler:    _ProductCatalogService_SearchProducts_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ShippingServiceClient is the client API for ShippingService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ShippingServiceClient interface {\n\tGetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error)\n\tShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error)\n}\n\ntype shippingServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient {\n\treturn &shippingServiceClient{cc}\n}\n\nfunc (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) {\n\tout := new(GetQuoteResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/GetQuote\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) {\n\tout := new(ShipOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/ShipOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ShippingServiceServer is the server API for ShippingService service.\ntype ShippingServiceServer interface {\n\tGetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error)\n\tShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error)\n}\n\nfunc RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) {\n\ts.RegisterService(&_ShippingService_serviceDesc, srv)\n}\n\nfunc _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetQuoteRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/GetQuote\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ShipOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/ShipOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ShippingService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ShippingService\",\n\tHandlerType: (*ShippingServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetQuote\",\n\t\t\tHandler:    _ShippingService_GetQuote_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"ShipOrder\",\n\t\t\tHandler:    _ShippingService_ShipOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CurrencyServiceClient is the client API for CurrencyService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CurrencyServiceClient interface {\n\tGetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error)\n\tConvert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error)\n}\n\ntype currencyServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient {\n\treturn &currencyServiceClient{cc}\n}\n\nfunc (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) {\n\tout := new(GetSupportedCurrenciesResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/GetSupportedCurrencies\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) {\n\tout := new(Money)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/Convert\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CurrencyServiceServer is the server API for CurrencyService service.\ntype CurrencyServiceServer interface {\n\tGetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error)\n\tConvert(context.Context, *CurrencyConversionRequest) (*Money, error)\n}\n\nfunc RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) {\n\ts.RegisterService(&_CurrencyService_serviceDesc, srv)\n}\n\nfunc _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/GetSupportedCurrencies\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(CurrencyConversionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/Convert\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CurrencyService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CurrencyService\",\n\tHandlerType: (*CurrencyServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetSupportedCurrencies\",\n\t\t\tHandler:    _CurrencyService_GetSupportedCurrencies_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"Convert\",\n\t\t\tHandler:    _CurrencyService_Convert_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// PaymentServiceClient is the client API for PaymentService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype PaymentServiceClient interface {\n\tCharge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error)\n}\n\ntype paymentServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient {\n\treturn &paymentServiceClient{cc}\n}\n\nfunc (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) {\n\tout := new(ChargeResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.PaymentService/Charge\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// PaymentServiceServer is the server API for PaymentService service.\ntype PaymentServiceServer interface {\n\tCharge(context.Context, *ChargeRequest) (*ChargeResponse, error)\n}\n\nfunc RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) {\n\ts.RegisterService(&_PaymentService_serviceDesc, srv)\n}\n\nfunc _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ChargeRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.PaymentService/Charge\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _PaymentService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.PaymentService\",\n\tHandlerType: (*PaymentServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Charge\",\n\t\t\tHandler:    _PaymentService_Charge_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// EmailServiceClient is the client API for EmailService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype EmailServiceClient interface {\n\tSendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype emailServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient {\n\treturn &emailServiceClient{cc}\n}\n\nfunc (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.EmailService/SendOrderConfirmation\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// EmailServiceServer is the server API for EmailService service.\ntype EmailServiceServer interface {\n\tSendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error)\n}\n\nfunc RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) {\n\ts.RegisterService(&_EmailService_serviceDesc, srv)\n}\n\nfunc _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SendOrderConfirmationRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.EmailService/SendOrderConfirmation\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _EmailService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.EmailService\",\n\tHandlerType: (*EmailServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"SendOrderConfirmation\",\n\t\t\tHandler:    _EmailService_SendOrderConfirmation_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CheckoutServiceClient is the client API for CheckoutService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CheckoutServiceClient interface {\n\tPlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error)\n}\n\ntype checkoutServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient {\n\treturn &checkoutServiceClient{cc}\n}\n\nfunc (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) {\n\tout := new(PlaceOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CheckoutService/PlaceOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CheckoutServiceServer is the server API for CheckoutService service.\ntype CheckoutServiceServer interface {\n\tPlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error)\n}\n\nfunc RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) {\n\ts.RegisterService(&_CheckoutService_serviceDesc, srv)\n}\n\nfunc _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PlaceOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CheckoutService/PlaceOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CheckoutService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CheckoutService\",\n\tHandlerType: (*CheckoutServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"PlaceOrder\",\n\t\t\tHandler:    _CheckoutService_PlaceOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// AdServiceClient is the client API for AdService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype AdServiceClient interface {\n\tGetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error)\n}\n\ntype adServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient {\n\treturn &adServiceClient{cc}\n}\n\nfunc (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) {\n\tout := new(AdResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.AdService/GetAds\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// AdServiceServer is the server API for AdService service.\ntype AdServiceServer interface {\n\tGetAds(context.Context, *AdRequest) (*AdResponse, error)\n}\n\nfunc RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) {\n\ts.RegisterService(&_AdService_serviceDesc, srv)\n}\n\nfunc _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AdRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.AdService/GetAds\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _AdService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.AdService\",\n\tHandlerType: (*AdServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetAds\",\n\t\t\tHandler:    _AdService_GetAds_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\nfunc init() { proto.RegisterFile(\"demo.proto\", fileDescriptor_ca53982754088a9d) }\n\nvar fileDescriptor_ca53982754088a9d = []byte{\n\t// 1500 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7,\n\t0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81,\n\t0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0,\n\t0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc,\n\t0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8,\n\t0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8,\n\t0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29,\n\t0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88,\n\t0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20,\n\t0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93,\n\t0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0,\n\t0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad,\n\t0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e,\n\t0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85,\n\t0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32,\n\t0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20,\n\t0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2,\n\t0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7,\n\t0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d,\n\t0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8,\n\t0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93,\n\t0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b,\n\t0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28,\n\t0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04,\n\t0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72,\n\t0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99,\n\t0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab,\n\t0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7,\n\t0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26,\n\t0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f,\n\t0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0,\n\t0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07,\n\t0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe,\n\t0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34,\n\t0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52,\n\t0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3,\n\t0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11,\n\t0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63,\n\t0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13,\n\t0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49,\n\t0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a,\n\t0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29,\n\t0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca,\n\t0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55,\n\t0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71,\n\t0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97,\n\t0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d,\n\t0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff,\n\t0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb,\n\t0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1,\n\t0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8,\n\t0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4,\n\t0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0,\n\t0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69,\n\t0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb,\n\t0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d,\n\t0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7,\n\t0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99,\n\t0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98,\n\t0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9,\n\t0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02,\n\t0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d,\n\t0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d,\n\t0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa,\n\t0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9,\n\t0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7,\n\t0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce,\n\t0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47,\n\t0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d,\n\t0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23,\n\t0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac,\n\t0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca,\n\t0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb,\n\t0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99,\n\t0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe,\n\t0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff,\n\t0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07,\n\t0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87,\n\t0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8,\n\t0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33,\n\t0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93,\n\t0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2,\n\t0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43,\n\t0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6,\n\t0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31,\n\t0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21,\n\t0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc,\n\t0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43,\n\t0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd,\n\t0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2,\n\t0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f,\n\t0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a,\n\t0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b,\n\t0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00,\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_frontend_genproto]\n\nPATH=$PATH:$GOPATH/bin\nprotodir=../../pb\n\nprotoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto\n\n# [END gke_frontend_genproto]"
  },
  {
    "path": "microservices-demo/src/frontend/go.mod",
    "content": "module github.com/GoogleCloudPlatform/microservices-demo/src/frontend\n\ngo 1.18\n\nrequire (\n\tcloud.google.com/go v0.104.0\n\tcloud.google.com/go/compute v1.7.0\n\tcloud.google.com/go/profiler v0.3.0\n\tcontrib.go.opencensus.io/exporter/jaeger v0.2.1\n\tcontrib.go.opencensus.io/exporter/stackdriver v0.13.12\n\tgithub.com/golang/protobuf v1.5.2\n\tgithub.com/google/uuid v1.3.0\n\tgithub.com/gorilla/mux v1.8.0\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/sirupsen/logrus v1.8.1\n\tgo.opencensus.io v0.23.0\n\tgolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b\n\tgoogle.golang.org/grpc v1.48.0\n)\n\nrequire (\n\tcloud.google.com/go/monitoring v1.1.0 // indirect\n\tcloud.google.com/go/trace v1.0.0 // indirect\n\tgithub.com/aws/aws-sdk-go v1.43.31 // indirect\n\tgithub.com/census-instrumentation/opencensus-proto v0.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.1.1 // indirect\n\tgithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect\n\tgithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/google/go-cmp v0.5.8 // indirect\n\tgithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect\n\tgithub.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.4.0 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/prometheus/prometheus v2.5.0+incompatible // indirect\n\tgithub.com/uber/jaeger-client-go v2.25.0+incompatible // indirect\n\tgolang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect\n\tgolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect\n\tgolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgoogle.golang.org/api v0.93.0 // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc // indirect\n\tgoogle.golang.org/protobuf v1.28.1 // indirect\n)\n"
  },
  {
    "path": "microservices-demo/src/frontend/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8=\ncloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=\ncloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0=\ncloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=\ncloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8=\ncloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk=\ncloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo=\ncloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=\ncloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ=\ncloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4=\ncloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo=\ncloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=\ncloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=\ngithub.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=\ngithub.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0=\ngithub.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=\ngithub.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa h1:7MYGT2XEMam7Mtzv1yDUYXANedWvwk3HKkR3MyGowy8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw=\ngithub.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=\ngithub.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=\ngolang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g=\ngolang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0=\ngolang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=\ngolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=\ngolang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s=\ngolang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngolang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/api v0.80.0 h1:IQWaGVCYnsm4MO3hh+WtSXMzMzuyFx/fuR8qkN3A0Qo=\ngoogle.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=\ngoogle.golang.org/api v0.84.0 h1:NMB9J4cCxs9xEm+1Z9QiO3eFvn7EnQj3Eo3hN6ugVlg=\ngoogle.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=\ngoogle.golang.org/api v0.93.0 h1:T2xt9gi0gHdxdnRkVQhT8mIvPaXKNsDNWz+L696M66M=\ngoogle.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220523171625-347a074981d8 h1:4NSrVrQGh6+UqBEd+Kwdh6ZDwESH0Sj2bNUQN+VjoQk=\ngoogle.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220617124728-180714bec0ad h1:kqrS+lhvaMHCxul6sKQvKJ8nAAhlVItmZV822hYFH/U=\ngoogle.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=\ngoogle.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc h1:Nf+EdcTLHR8qDNN/KfkQL0u0ssxt9OhbaWCl5C0ucEI=\ngoogle.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=\ngoogle.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=\ngoogle.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "microservices-demo/src/frontend/handlers.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"html/template\"\n\t\"math/rand\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gorilla/mux\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto\"\n\t\"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/money\"\n)\n\ntype platformDetails struct {\n\tcss      string\n\tprovider string\n}\n\nvar (\n\tisCymbalBrand = \"true\" == strings.ToLower(os.Getenv(\"CYMBAL_BRANDING\"))\n\ttemplates     = template.Must(template.New(\"\").\n\t\t\tFuncs(template.FuncMap{\n\t\t\t\"renderMoney\":        renderMoney,\n\t\t\t\"renderCurrencyLogo\": renderCurrencyLogo,\n\t\t}).ParseGlob(\"templates/*.html\"))\n\tplat platformDetails\n)\n\nvar validEnvs = []string{\"local\", \"gcp\", \"azure\", \"aws\", \"onprem\", \"alibaba\"}\n\nfunc (fe *frontendServer) homeHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.WithField(\"currency\", currentCurrency(r)).Info(\"home\")\n\tcurrencies, err := fe.getCurrencies(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve currencies\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tproducts, err := fe.getProducts(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve products\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tcart, err := fe.getCart(r.Context(), sessionID(r))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\ttype productView struct {\n\t\tItem  *pb.Product\n\t\tPrice *pb.Money\n\t}\n\tps := make([]productView, len(products))\n\tfor i, p := range products {\n\t\tprice, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))\n\t\tif err != nil {\n\t\t\trenderHTTPError(log, r, w, errors.Wrapf(err, \"failed to do currency conversion for product %s\", p.GetId()), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tps[i] = productView{p, price}\n\t}\n\n\t// Set ENV_PLATFORM (default to local if not set; use env var if set; otherwise detect GCP, which overrides env)_\n\tvar env = os.Getenv(\"ENV_PLATFORM\")\n\t// Only override from env variable if set + valid env\n\tif env == \"\" || stringinSlice(validEnvs, env) == false {\n\t\tfmt.Println(\"env platform is either empty or invalid\")\n\t\tenv = \"local\"\n\t}\n\t// Autodetect GCP\n\taddrs, err := net.LookupHost(\"metadata.google.internal.\")\n\tif err == nil && len(addrs) >= 0 {\n\t\tlog.Debugf(\"Detected Google metadata server: %v, setting ENV_PLATFORM to GCP.\", addrs)\n\t\tenv = \"gcp\"\n\t}\n\n\tlog.Debugf(\"ENV_PLATFORM is: %s\", env)\n\tplat = platformDetails{}\n\tplat.setPlatformDetails(strings.ToLower(env))\n\n\tif err := templates.ExecuteTemplate(w, \"home\", map[string]interface{}{\n\t\t\"session_id\":        sessionID(r),\n\t\t\"request_id\":        r.Context().Value(ctxKeyRequestID{}),\n\t\t\"user_currency\":     currentCurrency(r),\n\t\t\"show_currency\":     true,\n\t\t\"currencies\":        currencies,\n\t\t\"products\":          ps,\n\t\t\"cart_size\":         cartSize(cart),\n\t\t\"banner_color\":      os.Getenv(\"BANNER_COLOR\"), // illustrates canary deployments\n\t\t\"ad\":                fe.chooseAd(r.Context(), []string{}, log),\n\t\t\"platform_css\":      plat.css,\n\t\t\"platform_name\":     plat.provider,\n\t\t\"is_cymbal_brand\":   isCymbalBrand,\n\t\t\"deploymentDetails\": deploymentDetailsMap,\n\t}); err != nil {\n\t\tlog.Error(err)\n\t}\n}\n\nfunc (plat *platformDetails) setPlatformDetails(env string) {\n\tif env == \"aws\" {\n\t\tplat.provider = \"AWS\"\n\t\tplat.css = \"aws-platform\"\n\t} else if env == \"onprem\" {\n\t\tplat.provider = \"On-Premises\"\n\t\tplat.css = \"onprem-platform\"\n\t} else if env == \"azure\" {\n\t\tplat.provider = \"Azure\"\n\t\tplat.css = \"azure-platform\"\n\t} else if env == \"gcp\" {\n\t\tplat.provider = \"Google Cloud\"\n\t\tplat.css = \"gcp-platform\"\n\t} else if env == \"alibaba\" {\n\t\tplat.provider = \"Alibaba Cloud\"\n\t\tplat.css = \"alibaba-platform\"\n\t} else {\n\t\tplat.provider = \"local\"\n\t\tplat.css = \"local\"\n\t}\n}\n\nfunc (fe *frontendServer) productHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tid := mux.Vars(r)[\"id\"]\n\tif id == \"\" {\n\t\trenderHTTPError(log, r, w, errors.New(\"product id not specified\"), http.StatusBadRequest)\n\t\treturn\n\t}\n\tlog.WithField(\"id\", id).WithField(\"currency\", currentCurrency(r)).\n\t\tDebug(\"serving product page\")\n\n\tp, err := fe.getProduct(r.Context(), id)\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve product\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tcurrencies, err := fe.getCurrencies(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve currencies\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tcart, err := fe.getCart(r.Context(), sessionID(r))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tprice, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to convert currency\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\trecommendations, err := fe.getRecommendations(r.Context(), sessionID(r), []string{id})\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to get product recommendations\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tproduct := struct {\n\t\tItem  *pb.Product\n\t\tPrice *pb.Money\n\t}{p, price}\n\n\tif err := templates.ExecuteTemplate(w, \"product\", map[string]interface{}{\n\t\t\"session_id\":        sessionID(r),\n\t\t\"request_id\":        r.Context().Value(ctxKeyRequestID{}),\n\t\t\"ad\":                fe.chooseAd(r.Context(), p.Categories, log),\n\t\t\"user_currency\":     currentCurrency(r),\n\t\t\"show_currency\":     true,\n\t\t\"currencies\":        currencies,\n\t\t\"product\":           product,\n\t\t\"recommendations\":   recommendations,\n\t\t\"cart_size\":         cartSize(cart),\n\t\t\"platform_css\":      plat.css,\n\t\t\"platform_name\":     plat.provider,\n\t\t\"is_cymbal_brand\":   isCymbalBrand,\n\t\t\"deploymentDetails\": deploymentDetailsMap,\n\t}); err != nil {\n\t\tlog.Println(err)\n\t}\n}\n\nfunc (fe *frontendServer) addToCartHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tquantity, _ := strconv.ParseUint(r.FormValue(\"quantity\"), 10, 32)\n\tproductID := r.FormValue(\"product_id\")\n\tif productID == \"\" || quantity == 0 {\n\t\trenderHTTPError(log, r, w, errors.New(\"invalid form input\"), http.StatusBadRequest)\n\t\treturn\n\t}\n\tlog.WithField(\"product\", productID).WithField(\"quantity\", quantity).Debug(\"adding to cart\")\n\n\tp, err := fe.getProduct(r.Context(), productID)\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve product\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif err := fe.insertCart(r.Context(), sessionID(r), p.GetId(), int32(quantity)); err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to add to cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tw.Header().Set(\"location\", \"/cart\")\n\tw.WriteHeader(http.StatusFound)\n}\n\nfunc (fe *frontendServer) emptyCartHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.Debug(\"emptying cart\")\n\n\tif err := fe.emptyCart(r.Context(), sessionID(r)); err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to empty cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tw.Header().Set(\"location\", \"/\")\n\tw.WriteHeader(http.StatusFound)\n}\n\nfunc (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.Debug(\"view user cart\")\n\tcurrencies, err := fe.getCurrencies(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve currencies\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tcart, err := fe.getCart(r.Context(), sessionID(r))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve cart\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\trecommendations, err := fe.getRecommendations(r.Context(), sessionID(r), cartIDs(cart))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to get product recommendations\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tshippingCost, err := fe.getShippingQuote(r.Context(), cart, currentCurrency(r))\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to get shipping quote\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\ttype cartItemView struct {\n\t\tItem     *pb.Product\n\t\tQuantity int32\n\t\tPrice    *pb.Money\n\t}\n\titems := make([]cartItemView, len(cart))\n\ttotalPrice := pb.Money{CurrencyCode: currentCurrency(r)}\n\tfor i, item := range cart {\n\t\tp, err := fe.getProduct(r.Context(), item.GetProductId())\n\t\tif err != nil {\n\t\t\trenderHTTPError(log, r, w, errors.Wrapf(err, \"could not retrieve product #%s\", item.GetProductId()), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t\tprice, err := fe.convertCurrency(r.Context(), p.GetPriceUsd(), currentCurrency(r))\n\t\tif err != nil {\n\t\t\trenderHTTPError(log, r, w, errors.Wrapf(err, \"could not convert currency for product #%s\", item.GetProductId()), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\tmultPrice := money.MultiplySlow(*price, uint32(item.GetQuantity()))\n\t\titems[i] = cartItemView{\n\t\t\tItem:     p,\n\t\t\tQuantity: item.GetQuantity(),\n\t\t\tPrice:    &multPrice}\n\t\ttotalPrice = money.Must(money.Sum(totalPrice, multPrice))\n\t}\n\ttotalPrice = money.Must(money.Sum(totalPrice, *shippingCost))\n\tyear := time.Now().Year()\n\n\tif err := templates.ExecuteTemplate(w, \"cart\", map[string]interface{}{\n\t\t\"session_id\":        sessionID(r),\n\t\t\"request_id\":        r.Context().Value(ctxKeyRequestID{}),\n\t\t\"user_currency\":     currentCurrency(r),\n\t\t\"currencies\":        currencies,\n\t\t\"recommendations\":   recommendations,\n\t\t\"cart_size\":         cartSize(cart),\n\t\t\"shipping_cost\":     shippingCost,\n\t\t\"show_currency\":     true,\n\t\t\"total_cost\":        totalPrice,\n\t\t\"items\":             items,\n\t\t\"expiration_years\":  []int{year, year + 1, year + 2, year + 3, year + 4},\n\t\t\"platform_css\":      plat.css,\n\t\t\"platform_name\":     plat.provider,\n\t\t\"is_cymbal_brand\":   isCymbalBrand,\n\t\t\"deploymentDetails\": deploymentDetailsMap,\n\t}); err != nil {\n\t\tlog.Println(err)\n\t}\n}\n\nfunc (fe *frontendServer) placeOrderHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.Debug(\"placing order\")\n\n\tvar (\n\t\temail         = r.FormValue(\"email\")\n\t\tstreetAddress = r.FormValue(\"street_address\")\n\t\tzipCode, _    = strconv.ParseInt(r.FormValue(\"zip_code\"), 10, 32)\n\t\tcity          = r.FormValue(\"city\")\n\t\tstate         = r.FormValue(\"state\")\n\t\tcountry       = r.FormValue(\"country\")\n\t\tccNumber      = r.FormValue(\"credit_card_number\")\n\t\tccMonth, _    = strconv.ParseInt(r.FormValue(\"credit_card_expiration_month\"), 10, 32)\n\t\tccYear, _     = strconv.ParseInt(r.FormValue(\"credit_card_expiration_year\"), 10, 32)\n\t\tccCVV, _      = strconv.ParseInt(r.FormValue(\"credit_card_cvv\"), 10, 32)\n\t)\n\n\torder, err := pb.NewCheckoutServiceClient(fe.checkoutSvcConn).\n\t\tPlaceOrder(r.Context(), &pb.PlaceOrderRequest{\n\t\t\tEmail: email,\n\t\t\tCreditCard: &pb.CreditCardInfo{\n\t\t\t\tCreditCardNumber:          ccNumber,\n\t\t\t\tCreditCardExpirationMonth: int32(ccMonth),\n\t\t\t\tCreditCardExpirationYear:  int32(ccYear),\n\t\t\t\tCreditCardCvv:             int32(ccCVV)},\n\t\t\tUserId:       sessionID(r),\n\t\t\tUserCurrency: currentCurrency(r),\n\t\t\tAddress: &pb.Address{\n\t\t\t\tStreetAddress: streetAddress,\n\t\t\t\tCity:          city,\n\t\t\t\tState:         state,\n\t\t\t\tZipCode:       int32(zipCode),\n\t\t\t\tCountry:       country},\n\t\t})\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"failed to complete the order\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tlog.WithField(\"order\", order.GetOrder().GetOrderId()).Info(\"order placed\")\n\n\torder.GetOrder().GetItems()\n\trecommendations, _ := fe.getRecommendations(r.Context(), sessionID(r), nil)\n\n\ttotalPaid := *order.GetOrder().GetShippingCost()\n\tfor _, v := range order.GetOrder().GetItems() {\n\t\tmultPrice := money.MultiplySlow(*v.GetCost(), uint32(v.GetItem().GetQuantity()))\n\t\ttotalPaid = money.Must(money.Sum(totalPaid, multPrice))\n\t}\n\n\tcurrencies, err := fe.getCurrencies(r.Context())\n\tif err != nil {\n\t\trenderHTTPError(log, r, w, errors.Wrap(err, \"could not retrieve currencies\"), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif err := templates.ExecuteTemplate(w, \"order\", map[string]interface{}{\n\t\t\"session_id\":        sessionID(r),\n\t\t\"request_id\":        r.Context().Value(ctxKeyRequestID{}),\n\t\t\"user_currency\":     currentCurrency(r),\n\t\t\"show_currency\":     false,\n\t\t\"currencies\":        currencies,\n\t\t\"order\":             order.GetOrder(),\n\t\t\"total_paid\":        &totalPaid,\n\t\t\"recommendations\":   recommendations,\n\t\t\"platform_css\":      plat.css,\n\t\t\"platform_name\":     plat.provider,\n\t\t\"is_cymbal_brand\":   isCymbalBrand,\n\t\t\"deploymentDetails\": deploymentDetailsMap,\n\t}); err != nil {\n\t\tlog.Println(err)\n\t}\n}\n\nfunc (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tlog.Debug(\"logging out\")\n\tfor _, c := range r.Cookies() {\n\t\tc.Expires = time.Now().Add(-time.Hour * 24 * 365)\n\t\tc.MaxAge = -1\n\t\thttp.SetCookie(w, c)\n\t}\n\tw.Header().Set(\"Location\", \"/\")\n\tw.WriteHeader(http.StatusFound)\n}\n\nfunc (fe *frontendServer) setCurrencyHandler(w http.ResponseWriter, r *http.Request) {\n\tlog := r.Context().Value(ctxKeyLog{}).(logrus.FieldLogger)\n\tcur := r.FormValue(\"currency_code\")\n\tlog.WithField(\"curr.new\", cur).WithField(\"curr.old\", currentCurrency(r)).\n\t\tDebug(\"setting currency\")\n\n\tif cur != \"\" {\n\t\thttp.SetCookie(w, &http.Cookie{\n\t\t\tName:   cookieCurrency,\n\t\t\tValue:  cur,\n\t\t\tMaxAge: cookieMaxAge,\n\t\t})\n\t}\n\treferer := r.Header.Get(\"referer\")\n\tif referer == \"\" {\n\t\treferer = \"/\"\n\t}\n\tw.Header().Set(\"Location\", referer)\n\tw.WriteHeader(http.StatusFound)\n}\n\n// chooseAd queries for advertisements available and randomly chooses one, if\n// available. It ignores the error retrieving the ad since it is not critical.\nfunc (fe *frontendServer) chooseAd(ctx context.Context, ctxKeys []string, log logrus.FieldLogger) *pb.Ad {\n\tads, err := fe.getAd(ctx, ctxKeys)\n\tif err != nil {\n\t\tlog.WithField(\"error\", err).Warn(\"failed to retrieve ads\")\n\t\treturn nil\n\t}\n\treturn ads[rand.Intn(len(ads))]\n}\n\nfunc renderHTTPError(log logrus.FieldLogger, r *http.Request, w http.ResponseWriter, err error, code int) {\n\tlog.WithField(\"error\", err).Error(\"request error\")\n\terrMsg := fmt.Sprintf(\"%+v\", err)\n\n\tw.WriteHeader(code)\n\n\tif templateErr := templates.ExecuteTemplate(w, \"error\", map[string]interface{}{\n\t\t\"session_id\":        sessionID(r),\n\t\t\"request_id\":        r.Context().Value(ctxKeyRequestID{}),\n\t\t\"error\":             errMsg,\n\t\t\"status_code\":       code,\n\t\t\"status\":            http.StatusText(code),\n\t\t\"deploymentDetails\": deploymentDetailsMap,\n\t}); templateErr != nil {\n\t\tlog.Println(templateErr)\n\t}\n}\n\nfunc currentCurrency(r *http.Request) string {\n\tc, _ := r.Cookie(cookieCurrency)\n\tif c != nil {\n\t\treturn c.Value\n\t}\n\treturn defaultCurrency\n}\n\nfunc sessionID(r *http.Request) string {\n\tv := r.Context().Value(ctxKeySessionID{})\n\tif v != nil {\n\t\treturn v.(string)\n\t}\n\treturn \"\"\n}\n\nfunc cartIDs(c []*pb.CartItem) []string {\n\tout := make([]string, len(c))\n\tfor i, v := range c {\n\t\tout[i] = v.GetProductId()\n\t}\n\treturn out\n}\n\n// get total # of items in cart\nfunc cartSize(c []*pb.CartItem) int {\n\tcartSize := 0\n\tfor _, item := range c {\n\t\tcartSize += int(item.GetQuantity())\n\t}\n\treturn cartSize\n}\n\nfunc renderMoney(money pb.Money) string {\n\tcurrencyLogo := renderCurrencyLogo(money.GetCurrencyCode())\n\treturn fmt.Sprintf(\"%s%d.%02d\", currencyLogo, money.GetUnits(), money.GetNanos()/10000000)\n}\n\nfunc renderCurrencyLogo(currencyCode string) string {\n\tlogos := map[string]string{\n\t\t\"USD\": \"$\",\n\t\t\"CAD\": \"$\",\n\t\t\"JPY\": \"¥\",\n\t\t\"EUR\": \"€\",\n\t\t\"TRY\": \"₺\",\n\t\t\"GBP\": \"£\",\n\t}\n\n\tlogo := \"$\" //default\n\tif val, ok := logos[currencyCode]; ok {\n\t\tlogo = val\n\t}\n\treturn logo\n}\n\nfunc stringinSlice(slice []string, val string) bool {\n\tfor _, item := range slice {\n\t\tif item == val {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/main.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"cloud.google.com/go/profiler\"\n\t\"contrib.go.opencensus.io/exporter/jaeger\"\n\t\"contrib.go.opencensus.io/exporter/stackdriver\"\n\t\"github.com/gorilla/mux\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\t\"go.opencensus.io/plugin/ocgrpc\"\n\t\"go.opencensus.io/plugin/ochttp\"\n\t\"go.opencensus.io/plugin/ochttp/propagation/b3\"\n\t\"go.opencensus.io/stats/view\"\n\t\"go.opencensus.io/trace\"\n\t\"google.golang.org/grpc\"\n)\n\nconst (\n\tport            = \"8080\"\n\tdefaultCurrency = \"USD\"\n\tcookieMaxAge    = 60 * 60 * 48\n\n\tcookiePrefix    = \"shop_\"\n\tcookieSessionID = cookiePrefix + \"session-id\"\n\tcookieCurrency  = cookiePrefix + \"currency\"\n)\n\nvar (\n\twhitelistedCurrencies = map[string]bool{\n\t\t\"USD\": true,\n\t\t\"EUR\": true,\n\t\t\"CAD\": true,\n\t\t\"JPY\": true,\n\t\t\"GBP\": true,\n\t\t\"TRY\": true}\n)\n\ntype ctxKeySessionID struct{}\n\ntype frontendServer struct {\n\tproductCatalogSvcAddr string\n\tproductCatalogSvcConn *grpc.ClientConn\n\n\tcurrencySvcAddr string\n\tcurrencySvcConn *grpc.ClientConn\n\n\tcartSvcAddr string\n\tcartSvcConn *grpc.ClientConn\n\n\trecommendationSvcAddr string\n\trecommendationSvcConn *grpc.ClientConn\n\n\tcheckoutSvcAddr string\n\tcheckoutSvcConn *grpc.ClientConn\n\n\tshippingSvcAddr string\n\tshippingSvcConn *grpc.ClientConn\n\n\tadSvcAddr string\n\tadSvcConn *grpc.ClientConn\n}\n\nfunc main() {\n\tctx := context.Background()\n\tlog := logrus.New()\n\tlog.Level = logrus.DebugLevel\n\tlog.Formatter = &logrus.JSONFormatter{\n\t\tFieldMap: logrus.FieldMap{\n\t\t\tlogrus.FieldKeyTime:  \"timestamp\",\n\t\t\tlogrus.FieldKeyLevel: \"severity\",\n\t\t\tlogrus.FieldKeyMsg:   \"message\",\n\t\t},\n\t\tTimestampFormat: time.RFC3339Nano,\n\t}\n\tlog.Out = os.Stdout\n\n\tif os.Getenv(\"DISABLE_TRACING\") == \"\" {\n\t\tlog.Info(\"Tracing enabled.\")\n\t\tgo initTracing(log)\n\t} else {\n\t\tlog.Info(\"Tracing disabled.\")\n\t}\n\n\tif os.Getenv(\"DISABLE_PROFILER\") == \"\" {\n\t\tlog.Info(\"Profiling enabled.\")\n\t\tgo initProfiling(log, \"frontend\", \"1.0.0\")\n\t} else {\n\t\tlog.Info(\"Profiling disabled.\")\n\t}\n\n\tsrvPort := port\n\tif os.Getenv(\"PORT\") != \"\" {\n\t\tsrvPort = os.Getenv(\"PORT\")\n\t}\n\taddr := os.Getenv(\"LISTEN_ADDR\")\n\tsvc := new(frontendServer)\n\tmustMapEnv(&svc.productCatalogSvcAddr, \"PRODUCT_CATALOG_SERVICE_ADDR\")\n\tmustMapEnv(&svc.currencySvcAddr, \"CURRENCY_SERVICE_ADDR\")\n\tmustMapEnv(&svc.cartSvcAddr, \"CART_SERVICE_ADDR\")\n\tmustMapEnv(&svc.recommendationSvcAddr, \"RECOMMENDATION_SERVICE_ADDR\")\n\tmustMapEnv(&svc.checkoutSvcAddr, \"CHECKOUT_SERVICE_ADDR\")\n\tmustMapEnv(&svc.shippingSvcAddr, \"SHIPPING_SERVICE_ADDR\")\n\tmustMapEnv(&svc.adSvcAddr, \"AD_SERVICE_ADDR\")\n\n\tmustConnGRPC(ctx, &svc.currencySvcConn, svc.currencySvcAddr)\n\tmustConnGRPC(ctx, &svc.productCatalogSvcConn, svc.productCatalogSvcAddr)\n\tmustConnGRPC(ctx, &svc.cartSvcConn, svc.cartSvcAddr)\n\tmustConnGRPC(ctx, &svc.recommendationSvcConn, svc.recommendationSvcAddr)\n\tmustConnGRPC(ctx, &svc.shippingSvcConn, svc.shippingSvcAddr)\n\tmustConnGRPC(ctx, &svc.checkoutSvcConn, svc.checkoutSvcAddr)\n\tmustConnGRPC(ctx, &svc.adSvcConn, svc.adSvcAddr)\n\n\tr := mux.NewRouter()\n\tr.HandleFunc(\"/\", svc.homeHandler).Methods(http.MethodGet, http.MethodHead)\n\tr.HandleFunc(\"/product/{id}\", svc.productHandler).Methods(http.MethodGet, http.MethodHead)\n\tr.HandleFunc(\"/cart\", svc.viewCartHandler).Methods(http.MethodGet, http.MethodHead)\n\tr.HandleFunc(\"/cart\", svc.addToCartHandler).Methods(http.MethodPost)\n\tr.HandleFunc(\"/cart/empty\", svc.emptyCartHandler).Methods(http.MethodPost)\n\tr.HandleFunc(\"/setCurrency\", svc.setCurrencyHandler).Methods(http.MethodPost)\n\tr.HandleFunc(\"/logout\", svc.logoutHandler).Methods(http.MethodGet)\n\tr.HandleFunc(\"/cart/checkout\", svc.placeOrderHandler).Methods(http.MethodPost)\n\tr.PathPrefix(\"/static/\").Handler(http.StripPrefix(\"/static/\", http.FileServer(http.Dir(\"./static/\"))))\n\tr.HandleFunc(\"/robots.txt\", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, \"User-agent: *\\nDisallow: /\") })\n\tr.HandleFunc(\"/_healthz\", func(w http.ResponseWriter, _ *http.Request) { fmt.Fprint(w, \"ok\") })\n\n\tvar handler http.Handler = r\n\thandler = &logHandler{log: log, next: handler} // add logging\n\thandler = ensureSessionID(handler)             // add session ID\n\thandler = &ochttp.Handler{                     // add opencensus instrumentation\n\t\tHandler:     handler,\n\t\tPropagation: &b3.HTTPFormat{}}\n\n\tlog.Infof(\"starting server on \" + addr + \":\" + srvPort)\n\tlog.Fatal(http.ListenAndServe(addr+\":\"+srvPort, handler))\n}\n\nfunc initJaegerTracing(log logrus.FieldLogger) {\n\n\tsvcAddr := os.Getenv(\"JAEGER_SERVICE_ADDR\")\n\tif svcAddr == \"\" {\n\t\tlog.Info(\"jaeger initialization disabled.\")\n\t\treturn\n\t}\n\n\t// Register the Jaeger exporter to be able to retrieve\n\t// the collected spans.\n\texporter, err := jaeger.NewExporter(jaeger.Options{\n\t\tEndpoint: fmt.Sprintf(\"http://%s\", svcAddr),\n\t\tProcess: jaeger.Process{\n\t\t\tServiceName: \"frontend\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\ttrace.RegisterExporter(exporter)\n\tlog.Info(\"jaeger initialization completed.\")\n}\n\nfunc initStats(log logrus.FieldLogger, exporter *stackdriver.Exporter) {\n\tview.SetReportingPeriod(60 * time.Second)\n\tview.RegisterExporter(exporter)\n\tif err := view.Register(ochttp.DefaultServerViews...); err != nil {\n\t\tlog.Warn(\"Error registering http default server views\")\n\t} else {\n\t\tlog.Info(\"Registered http default server views\")\n\t}\n\tif err := view.Register(ocgrpc.DefaultClientViews...); err != nil {\n\t\tlog.Warn(\"Error registering grpc default client views\")\n\t} else {\n\t\tlog.Info(\"Registered grpc default client views\")\n\t}\n}\n\nfunc initStackdriverTracing(log logrus.FieldLogger) {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\tlog = log.WithField(\"retry\", i)\n\t\texporter, err := stackdriver.NewExporter(stackdriver.Options{})\n\t\tif err != nil {\n\t\t\t// log.Warnf is used since there are multiple backends (stackdriver & jaeger)\n\t\t\t// to store the traces. In production setup most likely you would use only one backend.\n\t\t\t// In that case you should use log.Fatalf.\n\t\t\tlog.Warnf(\"failed to initialize Stackdriver exporter: %+v\", err)\n\t\t} else {\n\t\t\ttrace.RegisterExporter(exporter)\n\t\t\tlog.Info(\"registered Stackdriver tracing\")\n\n\t\t\t// Register the views to collect server stats.\n\t\t\tinitStats(log, exporter)\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 20 * time.Duration(i)\n\t\tlog.Debugf(\"sleeping %v to retry initializing Stackdriver exporter\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver exporter after retrying, giving up\")\n}\n\nfunc initTracing(log logrus.FieldLogger) {\n\t// This is a demo app with low QPS. trace.AlwaysSample() is used here\n\t// to make sure traces are available for observation and analysis.\n\t// In a production environment or high QPS setup please use\n\t// trace.ProbabilitySampler set at the desired probability.\n\ttrace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})\n\n\tinitJaegerTracing(log)\n\tinitStackdriverTracing(log)\n\n}\n\nfunc initProfiling(log logrus.FieldLogger, service, version string) {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\tlog = log.WithField(\"retry\", i)\n\t\tif err := profiler.Start(profiler.Config{\n\t\t\tService:        service,\n\t\t\tServiceVersion: version,\n\t\t\t// ProjectID must be set if not running on GCP.\n\t\t\t// ProjectID: \"my-project\",\n\t\t}); err != nil {\n\t\t\tlog.Warnf(\"warn: failed to start profiler: %+v\", err)\n\t\t} else {\n\t\t\tlog.Info(\"started Stackdriver profiler\")\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Debugf(\"sleeping %v to retry initializing Stackdriver profiler\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"warning: could not initialize Stackdriver profiler after retrying, giving up\")\n}\n\nfunc mustMapEnv(target *string, envKey string) {\n\tv := os.Getenv(envKey)\n\tif v == \"\" {\n\t\tpanic(fmt.Sprintf(\"environment variable %q not set\", envKey))\n\t}\n\t*target = v\n}\n\nfunc mustConnGRPC(ctx context.Context, conn **grpc.ClientConn, addr string) {\n\tvar err error\n\tctx, cancel := context.WithTimeout(ctx, time.Second*3)\n\tdefer cancel()\n\t*conn, err = grpc.DialContext(ctx, addr,\n\t\tgrpc.WithInsecure(),\n\t\tgrpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\tpanic(errors.Wrapf(err, \"grpc: failed to connect %s\", addr))\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/middleware.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\t\"github.com/sirupsen/logrus\"\n)\n\ntype ctxKeyLog struct{}\ntype ctxKeyRequestID struct{}\n\ntype logHandler struct {\n\tlog  *logrus.Logger\n\tnext http.Handler\n}\n\ntype responseRecorder struct {\n\tb      int\n\tstatus int\n\tw      http.ResponseWriter\n}\n\nfunc (r *responseRecorder) Header() http.Header { return r.w.Header() }\n\nfunc (r *responseRecorder) Write(p []byte) (int, error) {\n\tif r.status == 0 {\n\t\tr.status = http.StatusOK\n\t}\n\tn, err := r.w.Write(p)\n\tr.b += n\n\treturn n, err\n}\n\nfunc (r *responseRecorder) WriteHeader(statusCode int) {\n\tr.status = statusCode\n\tr.w.WriteHeader(statusCode)\n}\n\nfunc (lh *logHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tctx := r.Context()\n\trequestID, _ := uuid.NewRandom()\n\tctx = context.WithValue(ctx, ctxKeyRequestID{}, requestID.String())\n\n\tstart := time.Now()\n\trr := &responseRecorder{w: w}\n\tlog := lh.log.WithFields(logrus.Fields{\n\t\t\"http.req.path\":   r.URL.Path,\n\t\t\"http.req.method\": r.Method,\n\t\t\"http.req.id\":     requestID.String(),\n\t})\n\tif v, ok := r.Context().Value(ctxKeySessionID{}).(string); ok {\n\t\tlog = log.WithField(\"session\", v)\n\t}\n\tlog.Debug(\"request started\")\n\tdefer func() {\n\t\tlog.WithFields(logrus.Fields{\n\t\t\t\"http.resp.took_ms\": int64(time.Since(start) / time.Millisecond),\n\t\t\t\"http.resp.status\":  rr.status,\n\t\t\t\"http.resp.bytes\":   rr.b}).Debugf(\"request complete\")\n\t}()\n\n\tctx = context.WithValue(ctx, ctxKeyLog{}, log)\n\tr = r.WithContext(ctx)\n\tlh.next.ServeHTTP(rr, r)\n}\n\nfunc ensureSessionID(next http.Handler) http.HandlerFunc {\n\treturn func(w http.ResponseWriter, r *http.Request) {\n\t\tvar sessionID string\n\t\tc, err := r.Cookie(cookieSessionID)\n\t\tif err == http.ErrNoCookie {\n\t\t\tu, _ := uuid.NewRandom()\n\t\t\tsessionID = u.String()\n\t\t\thttp.SetCookie(w, &http.Cookie{\n\t\t\t\tName:   cookieSessionID,\n\t\t\t\tValue:  sessionID,\n\t\t\t\tMaxAge: cookieMaxAge,\n\t\t\t})\n\t\t} else if err != nil {\n\t\t\treturn\n\t\t} else {\n\t\t\tsessionID = c.Value\n\t\t}\n\t\tctx := context.WithValue(r.Context(), ctxKeySessionID{}, sessionID)\n\t\tr = r.WithContext(ctx)\n\t\tnext.ServeHTTP(w, r)\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/money/money.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage money\n\nimport (\n\t\"errors\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto\"\n)\n\nconst (\n\tnanosMin = -999999999\n\tnanosMax = +999999999\n\tnanosMod = 1000000000\n)\n\nvar (\n\tErrInvalidValue        = errors.New(\"one of the specified money values is invalid\")\n\tErrMismatchingCurrency = errors.New(\"mismatching currency codes\")\n)\n\n// IsValid checks if specified value has a valid units/nanos signs and ranges.\nfunc IsValid(m pb.Money) bool {\n\treturn signMatches(m) && validNanos(m.GetNanos())\n}\n\nfunc signMatches(m pb.Money) bool {\n\treturn m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0)\n}\n\nfunc validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax }\n\n// IsZero returns true if the specified money value is equal to zero.\nfunc IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 }\n\n// IsPositive returns true if the specified money value is valid and is\n// positive.\nfunc IsPositive(m pb.Money) bool {\n\treturn IsValid(m) && m.GetUnits() > 0 || (m.GetUnits() == 0 && m.GetNanos() > 0)\n}\n\n// IsNegative returns true if the specified money value is valid and is\n// negative.\nfunc IsNegative(m pb.Money) bool {\n\treturn IsValid(m) && m.GetUnits() < 0 || (m.GetUnits() == 0 && m.GetNanos() < 0)\n}\n\n// AreSameCurrency returns true if values l and r have a currency code and\n// they are the same values.\nfunc AreSameCurrency(l, r pb.Money) bool {\n\treturn l.GetCurrencyCode() == r.GetCurrencyCode() && l.GetCurrencyCode() != \"\"\n}\n\n// AreEquals returns true if values l and r are the equal, including the\n// currency. This does not check validity of the provided values.\nfunc AreEquals(l, r pb.Money) bool {\n\treturn l.GetCurrencyCode() == r.GetCurrencyCode() &&\n\t\tl.GetUnits() == r.GetUnits() && l.GetNanos() == r.GetNanos()\n}\n\n// Negate returns the same amount with the sign negated.\nfunc Negate(m pb.Money) pb.Money {\n\treturn pb.Money{\n\t\tUnits:        -m.GetUnits(),\n\t\tNanos:        -m.GetNanos(),\n\t\tCurrencyCode: m.GetCurrencyCode()}\n}\n\n// Must panics if the given error is not nil. This can be used with other\n// functions like: \"m := Must(Sum(a,b))\".\nfunc Must(v pb.Money, err error) pb.Money {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn v\n}\n\n// Sum adds two values. Returns an error if one of the values are invalid or\n// currency codes are not matching (unless currency code is unspecified for\n// both).\nfunc Sum(l, r pb.Money) (pb.Money, error) {\n\tif !IsValid(l) || !IsValid(r) {\n\t\treturn pb.Money{}, ErrInvalidValue\n\t} else if l.GetCurrencyCode() != r.GetCurrencyCode() {\n\t\treturn pb.Money{}, ErrMismatchingCurrency\n\t}\n\tunits := l.GetUnits() + r.GetUnits()\n\tnanos := l.GetNanos() + r.GetNanos()\n\n\tif (units == 0 && nanos == 0) || (units > 0 && nanos >= 0) || (units < 0 && nanos <= 0) {\n\t\t// same sign <units, nanos>\n\t\tunits += int64(nanos / nanosMod)\n\t\tnanos = nanos % nanosMod\n\t} else {\n\t\t// different sign. nanos guaranteed to not to go over the limit\n\t\tif units > 0 {\n\t\t\tunits--\n\t\t\tnanos += nanosMod\n\t\t} else {\n\t\t\tunits++\n\t\t\tnanos -= nanosMod\n\t\t}\n\t}\n\n\treturn pb.Money{\n\t\tUnits:        units,\n\t\tNanos:        nanos,\n\t\tCurrencyCode: l.GetCurrencyCode()}, nil\n}\n\n// MultiplySlow is a slow multiplication operation done through adding the value\n// to itself n-1 times.\nfunc MultiplySlow(m pb.Money, n uint32) pb.Money {\n\tout := m\n\tfor n > 1 {\n\t\tout = Must(Sum(out, m))\n\t\tn--\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/money/money_test.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage money\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto\"\n)\n\nfunc mmc(u int64, n int32, c string) pb.Money { return pb.Money{Units: u, Nanos: n, CurrencyCode: c} }\nfunc mm(u int64, n int32) pb.Money            { return mmc(u, n, \"\") }\n\nfunc TestIsValid(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"valid -/-\", mm(-981273891273, -999999999), true},\n\t\t{\"invalid -/+\", mm(-981273891273, +999999999), false},\n\t\t{\"valid +/+\", mm(981273891273, 999999999), true},\n\t\t{\"invalid +/-\", mm(981273891273, -999999999), false},\n\t\t{\"invalid +/+overflow\", mm(3, 1000000000), false},\n\t\t{\"invalid +/-overflow\", mm(3, -1000000000), false},\n\t\t{\"invalid -/+overflow\", mm(-3, 1000000000), false},\n\t\t{\"invalid -/-overflow\", mm(-3, -1000000000), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsValid(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsValid(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsZero(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), true},\n\t\t{\"not-zero (-/+)\", mm(-1, +1), false},\n\t\t{\"not-zero (-/-)\", mm(-1, -1), false},\n\t\t{\"not-zero (+/+)\", mm(+1, +1), false},\n\t\t{\"not-zero (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsZero(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsZero(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsPositive(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), false},\n\t\t{\"positive (+/+)\", mm(+1, +1), true},\n\t\t{\"invalid (-/+)\", mm(-1, +1), false},\n\t\t{\"negative (-/-)\", mm(-1, -1), false},\n\t\t{\"invalid (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsPositive(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsPositive(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestIsNegative(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant bool\n\t}{\n\t\t{\"zero\", mm(0, 0), false},\n\t\t{\"positive (+/+)\", mm(+1, +1), false},\n\t\t{\"invalid (-/+)\", mm(-1, +1), false},\n\t\t{\"negative (-/-)\", mm(-1, -1), true},\n\t\t{\"invalid (+/-)\", mm(+1, -1), false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := IsNegative(tt.in); got != tt.want {\n\t\t\t\tt.Errorf(\"IsNegative(%v) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAreSameCurrency(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\"both empty currency\", args{mmc(1, 0, \"\"), mmc(2, 0, \"\")}, false},\n\t\t{\"left empty currency\", args{mmc(1, 0, \"\"), mmc(2, 0, \"USD\")}, false},\n\t\t{\"right empty currency\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"\")}, false},\n\t\t{\"mismatching\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"CAD\")}, false},\n\t\t{\"matching\", args{mmc(1, 0, \"USD\"), mmc(2, 0, \"USD\")}, true},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := AreSameCurrency(tt.args.l, tt.args.r); got != tt.want {\n\t\t\t\tt.Errorf(\"AreSameCurrency([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAreEquals(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname string\n\t\targs args\n\t\twant bool\n\t}{\n\t\t{\"equals\", args{mmc(1, 2, \"USD\"), mmc(1, 2, \"USD\")}, true},\n\t\t{\"mismatching currency\", args{mmc(1, 2, \"USD\"), mmc(1, 2, \"CAD\")}, false},\n\t\t{\"mismatching units\", args{mmc(10, 20, \"USD\"), mmc(1, 20, \"USD\")}, false},\n\t\t{\"mismatching nanos\", args{mmc(1, 2, \"USD\"), mmc(1, 20, \"USD\")}, false},\n\t\t{\"negated\", args{mmc(1, 2, \"USD\"), mmc(-1, -2, \"USD\")}, false},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := AreEquals(tt.args.l, tt.args.r); got != tt.want {\n\t\t\t\tt.Errorf(\"AreEquals([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestNegate(t *testing.T) {\n\ttests := []struct {\n\t\tname string\n\t\tin   pb.Money\n\t\twant pb.Money\n\t}{\n\t\t{\"zero\", mm(0, 0), mm(0, 0)},\n\t\t{\"negative\", mm(-1, -200), mm(1, 200)},\n\t\t{\"positive\", mm(1, 200), mm(-1, -200)},\n\t\t{\"carries currency code\", mmc(0, 0, \"XXX\"), mmc(0, 0, \"XXX\")},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tif got := Negate(tt.in); !AreEquals(got, tt.want) {\n\t\t\t\tt.Errorf(\"Negate([%v]) = %v, want %v\", tt.in, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMust_pass(t *testing.T) {\n\tv := Must(mm(2, 3), nil)\n\tif !AreEquals(v, mm(2, 3)) {\n\t\tt.Errorf(\"returned the wrong value: %v\", v)\n\t}\n}\n\nfunc TestMust_panic(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tt.Logf(\"panic captured: %v\", r)\n\t\t}\n\t}()\n\tMust(mm(2, 3), fmt.Errorf(\"some error\"))\n\tt.Fatal(\"this should not have executed due to the panic above\")\n}\n\nfunc TestSum(t *testing.T) {\n\ttype args struct {\n\t\tl pb.Money\n\t\tr pb.Money\n\t}\n\ttests := []struct {\n\t\tname    string\n\t\targs    args\n\t\twant    pb.Money\n\t\twantErr error\n\t}{\n\t\t{\"0+0=0\", args{mm(0, 0), mm(0, 0)}, mm(0, 0), nil},\n\t\t{\"Error: currency code on left\", args{mmc(0, 0, \"XXX\"), mm(0, 0)}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: currency code on right\", args{mm(0, 0), mmc(0, 0, \"YYY\")}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: currency code mismatch\", args{mmc(0, 0, \"AAA\"), mmc(0, 0, \"BBB\")}, mm(0, 0), ErrMismatchingCurrency},\n\t\t{\"Error: invalid +/-\", args{mm(+1, -1), mm(0, 0)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"Error: invalid -/+\", args{mm(0, 0), mm(-1, +2)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"Error: invalid nanos\", args{mm(0, 1000000000), mm(1, 0)}, mm(0, 0), ErrInvalidValue},\n\t\t{\"both positive (no carry)\", args{mm(2, 200000000), mm(2, 200000000)}, mm(4, 400000000), nil},\n\t\t{\"both positive (nanos=max)\", args{mm(2, 111111111), mm(2, 888888888)}, mm(4, 999999999), nil},\n\t\t{\"both positive (carry)\", args{mm(2, 200000000), mm(2, 900000000)}, mm(5, 100000000), nil},\n\t\t{\"both negative (no carry)\", args{mm(-2, -200000000), mm(-2, -200000000)}, mm(-4, -400000000), nil},\n\t\t{\"both negative (carry)\", args{mm(-2, -200000000), mm(-2, -900000000)}, mm(-5, -100000000), nil},\n\t\t{\"mixed (larger positive, just decimals)\", args{mm(11, 0), mm(-2, 0)}, mm(9, 0), nil},\n\t\t{\"mixed (larger negative, just decimals)\", args{mm(-11, 0), mm(2, 0)}, mm(-9, 0), nil},\n\t\t{\"mixed (larger positive, no borrow)\", args{mm(11, 100000000), mm(-2, -100000000)}, mm(9, 0), nil},\n\t\t{\"mixed (larger positive, with borrow)\", args{mm(11, 100000000), mm(-2, -9000000 /*.09*/)}, mm(9, 91000000 /*.091*/), nil},\n\t\t{\"mixed (larger negative, no borrow)\", args{mm(-11, -100000000), mm(2, 100000000)}, mm(-9, 0), nil},\n\t\t{\"mixed (larger negative, with borrow)\", args{mm(-11, -100000000), mm(2, 9000000 /*.09*/)}, mm(-9, -91000000 /*.091*/), nil},\n\t\t{\"0+negative\", args{mm(0, 0), mm(-2, -100000000)}, mm(-2, -100000000), nil},\n\t\t{\"negative+0\", args{mm(-2, -100000000), mm(0, 0)}, mm(-2, -100000000), nil},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot, err := Sum(tt.args.l, tt.args.r)\n\t\t\tif err != tt.wantErr {\n\t\t\t\tt.Errorf(\"Sum([%v],[%v]): expected err=\\\"%v\\\" got=\\\"%v\\\"\", tt.args.l, tt.args.r, tt.wantErr, err)\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(got, tt.want) {\n\t\t\t\tt.Errorf(\"Sum([%v],[%v]) = %v, want %v\", tt.args.l, tt.args.r, got, tt.want)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/rpc.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto\"\n\n\t\"github.com/pkg/errors\"\n)\n\nconst (\n\tavoidNoopCurrencyConversionRPC = false\n)\n\nfunc (fe *frontendServer) getCurrencies(ctx context.Context) ([]string, error) {\n\tcurrs, err := pb.NewCurrencyServiceClient(fe.currencySvcConn).\n\t\tGetSupportedCurrencies(ctx, &pb.Empty{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar out []string\n\tfor _, c := range currs.CurrencyCodes {\n\t\tif _, ok := whitelistedCurrencies[c]; ok {\n\t\t\tout = append(out, c)\n\t\t}\n\t}\n\treturn out, nil\n}\n\nfunc (fe *frontendServer) getProducts(ctx context.Context) ([]*pb.Product, error) {\n\tresp, err := pb.NewProductCatalogServiceClient(fe.productCatalogSvcConn).\n\t\tListProducts(ctx, &pb.Empty{})\n\treturn resp.GetProducts(), err\n}\n\nfunc (fe *frontendServer) getProduct(ctx context.Context, id string) (*pb.Product, error) {\n\tresp, err := pb.NewProductCatalogServiceClient(fe.productCatalogSvcConn).\n\t\tGetProduct(ctx, &pb.GetProductRequest{Id: id})\n\treturn resp, err\n}\n\nfunc (fe *frontendServer) getCart(ctx context.Context, userID string) ([]*pb.CartItem, error) {\n\tresp, err := pb.NewCartServiceClient(fe.cartSvcConn).GetCart(ctx, &pb.GetCartRequest{UserId: userID})\n\treturn resp.GetItems(), err\n}\n\nfunc (fe *frontendServer) emptyCart(ctx context.Context, userID string) error {\n\t_, err := pb.NewCartServiceClient(fe.cartSvcConn).EmptyCart(ctx, &pb.EmptyCartRequest{UserId: userID})\n\treturn err\n}\n\nfunc (fe *frontendServer) insertCart(ctx context.Context, userID, productID string, quantity int32) error {\n\t_, err := pb.NewCartServiceClient(fe.cartSvcConn).AddItem(ctx, &pb.AddItemRequest{\n\t\tUserId: userID,\n\t\tItem: &pb.CartItem{\n\t\t\tProductId: productID,\n\t\t\tQuantity:  quantity},\n\t})\n\treturn err\n}\n\nfunc (fe *frontendServer) convertCurrency(ctx context.Context, money *pb.Money, currency string) (*pb.Money, error) {\n\tif avoidNoopCurrencyConversionRPC && money.GetCurrencyCode() == currency {\n\t\treturn money, nil\n\t}\n\treturn pb.NewCurrencyServiceClient(fe.currencySvcConn).\n\t\tConvert(ctx, &pb.CurrencyConversionRequest{\n\t\t\tFrom:   money,\n\t\t\tToCode: currency})\n}\n\nfunc (fe *frontendServer) getShippingQuote(ctx context.Context, items []*pb.CartItem, currency string) (*pb.Money, error) {\n\tquote, err := pb.NewShippingServiceClient(fe.shippingSvcConn).GetQuote(ctx,\n\t\t&pb.GetQuoteRequest{\n\t\t\tAddress: nil,\n\t\t\tItems:   items})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tlocalized, err := fe.convertCurrency(ctx, quote.GetCostUsd(), currency)\n\treturn localized, errors.Wrap(err, \"failed to convert currency for shipping cost\")\n}\n\nfunc (fe *frontendServer) getRecommendations(ctx context.Context, userID string, productIDs []string) ([]*pb.Product, error) {\n\tresp, err := pb.NewRecommendationServiceClient(fe.recommendationSvcConn).ListRecommendations(ctx,\n\t\t&pb.ListRecommendationsRequest{UserId: userID, ProductIds: productIDs})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout := make([]*pb.Product, len(resp.GetProductIds()))\n\tfor i, v := range resp.GetProductIds() {\n\t\tp, err := fe.getProduct(ctx, v)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"failed to get recommended product info (#%s)\", v)\n\t\t}\n\t\tout[i] = p\n\t}\n\tif len(out) > 4 {\n\t\tout = out[:4] // take only first four to fit the UI\n\t}\n\treturn out, err\n}\n\nfunc (fe *frontendServer) getAd(ctx context.Context, ctxKeys []string) ([]*pb.Ad, error) {\n\tctx, cancel := context.WithTimeout(ctx, time.Millisecond*100)\n\tdefer cancel()\n\n\tresp, err := pb.NewAdServiceClient(fe.adSvcConn).GetAds(ctx, &pb.AdRequest{\n\t\tContextKeys: ctxKeys,\n\t})\n\treturn resp.GetAds(), errors.Wrap(err, \"failed to get ads\")\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/static/images/credits.txt",
    "content": "folded-clothes-on-white-chair.jpg,,https://unsplash.com/photos/fr0J5-GIVyg\nfolded-clothes-on-white-chair-wide.jpg,,https://unsplash.com/photos/fr0J5-GIVyg\n"
  },
  {
    "path": "microservices-demo/src/frontend/static/styles/cart.css",
    "content": "/**\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n.cart-sections {\n    padding-bottom: 120px;\n    padding-top: 56px;\n    background-color: #F9F9F9;\n}\n\n.cart-sections h3 {\n    font-size: 36px;\n    font-weight: normal;\n}\n\n.cart-sections a.cymbal-button-primary:hover {\n    text-decoration: none;\n    color: white;\n}\n\n/* Empty Cart Section */\n\n.empty-cart-section {\n    max-width: 458px;\n    margin: auto;\n    text-align: center;\n}\n\n.empty-cart-section a {\n    display: inline-block; /* So margin-top works. */\n    margin-top: 32px;\n}\n\n.empty-cart-section a:hover {\n    color: white;\n    text-decoration: none;\n}\n\n/*  Cart Summary Section */\n\n.cart-summary-empty-cart-button {\n    margin-right: 10px;\n}\n\n.cart-summary-item-row,\n.cart-summary-shipping-row,\n.cart-summary-total-row {\n    padding-bottom: 24px;\n    padding-top: 24px;\n    border-top: solid 1px rgba(154, 160, 166, 0.5);\n}\n\n.cart-summary-item-row img {\n    border-radius: 20% 0 20% 20%;\n}\n\n.cart-summary-item-row-item-id-row {\n    font-size: 12px;\n    color: #5C6063;\n}\n\n.cart-summary-item-row h4 {\n    font-size: 18px;\n    font-weight: normal;\n}\n\n/* Stick item quantity and cost to the bottom (for wider screens). */\n@media (min-width: 768px) {\n    .cart-summary-item-row .row:last-child {\n        position: absolute;\n        bottom: 0px;\n        width: 100%;\n    }\n}\n\n/* Item cost (price). */\n.cart-summary-item-row .row:last-child strong {\n    font-weight: 500;\n}\n\n.cart-summary-total-row {\n    font-size: 28px;\n}\n\n/* Cart Checkout Form */\n\n.cart-checkout-form h3 {\n    margin-bottom: 0;\n}\n\n.payment-method-heading {\n    margin-top: 36px;\n}\n\n/* \"Place Order\" button */\n.cart-checkout-form .cymbal-button-primary {\n    margin-top: 36px;\n}"
  },
  {
    "path": "microservices-demo/src/frontend/static/styles/order.css",
    "content": "/**\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n.order {\n    background: #F9F9F9;\n}\n\n.order-complete-section {\n    max-width: 487px;\n    padding-top: 56px;\n    padding-bottom: 120px;\n}\n\n.order-complete-section h3 {\n    margin: 0;\n    font-size: 36px;\n    font-weight: normal;\n}\n\n.order-complete-section p {\n    margin-top: 8px;\n}\n\n.order-complete-section .padding-y-24 {\n    padding-bottom: 24px;\n    padding-top: 24px;\n}\n\n.order-complete-section .border-bottom-solid {\n    border-bottom: 1px solid rgba(154, 160, 166, 0.5);\n}\n\n.order-complete-section .cymbal-button-primary {\n    margin-top: 24px;\n}\n\n.order-complete-section a.cymbal-button-primary:hover {\n    text-decoration: none;\n    color: white;\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/static/styles/styles.css",
    "content": "/**\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/* General */\n\nhtml, body {\n  height: 100%;\n}\n\nbody {\n  color: #111111;\n  font-family: 'DM Sans', sans-serif;\n  display: flex;\n  flex-direction: column;\n}\n\n/* Header */\n\nheader {\n  background-color: #853B5C;\n  color: white;\n}\n\n/*\nThis allows the sub-navbar (white strip containing logo)\nto be as wide as the browser window.\n*/\nheader > div:nth-child(2).navbar.sub-navbar {\n  padding-left: 0;\n  padding-right: 0;\n}\nheader > div:nth-child(2) > .container {\n  max-width: none;\n}\n\nheader .cart-link {\n  position: relative;\n  display: block;\n  margin-left: 25px;\n  display: flex;\n  flex-flow: column;\n  align-items: center;\n  justify-content: center;\n}\n\nheader .cart-size-circle {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  position: absolute;\n  top: 24px;\n  left: 11px;\n  width: 16px;\n  height: 16px;\n  font-size: 11px;\n  border-radius: 4px 4px 0 4px;\n  color: white;\n  background-color: #853B5C;\n}\n\nheader .h-free-shipping {\n  font-size: 14px;\n}\n\nheader .h-controls {\n  display: flex;\n  justify-content: flex-end;\n}\n\nheader .h-control {\n  display: flex;\n  align-items: center;\n  font-size: 12px;\n  position: relative;\n  margin-left: 40px;\n  color: #605f64;\n}\n\nheader .h-control:first-child {\n  margin-left: 0;\n}\n\nheader .h-control input {\n  border: none;\n  padding: 0 31px 0 31px;\n  width: 250px;\n  height: 24px;\n  flex-shrink: 0;\n  background-color: #f2f2f2;\n  display: flex;\n  align-items: center;\n}\n\nheader .h-control input:focus {\n  outline: 0;\n  border: 0;\n  box-shadow: 0;\n}\n\nheader .icon {\n  width: 20px;\n  height: 20px;\n}\n\nheader .icon.search-icon {\n  width: 12px;\n  height: 13px;\n  position: absolute;\n  left: 10px;\n}\n\n/* The currency drop-down. */\n\nheader img.currency-icon, header span.currency-icon {\n  position: relative;\n  left: 35px;\n  top: -1px;\n  width: 20px;\n  display: inline-block;\n  height: 20px;\n}\n\nheader span.currency-icon {\n  font-size: 16px;\n  text-align: center;\n}\n\nheader .h-control select {\n  display: flex;\n  align-items: center;\n  background: transparent;\n  border-radius: 0;\n  border: 1px solid #acacac;\n  width: 130px;\n  height: 40px;\n  flex-shrink: 0;\n  padding: 1px 0 0 45px;\n  font-size: 16px;\n  border-radius: 8px;\n}\n\nheader .icon.arrow {\n  position: absolute;\n  right: 25px;\n  width: 10px;\n  height: 5px;\n}\n\nheader .h-control::-webkit-input-placeholder {\n  /* Chrome/Opera/Safari */\n  font-size: 12px;\n  color: #605f64;\n}\n\nheader .h-control::-moz-placeholder {\n  /* Firefox 19+ */\n  font-size: 12px;\n  color: #605f64;\n}\n\nheader .h-control :-ms-input-placeholder {\n  /* IE 10+ */\n  font-size: 12px;\n  color: #605f64;\n}\n\nheader .h-control :-moz-placeholder {\n  /* Firefox 18- */\n  font-size: 12px;\n  color: #605f64;\n}\n\nheader .navbar.sub-navbar {\n  height: 60px;\n  background-color: white;\n  font-size: 15px;\n  color: #b4b2bb;\n  padding-top: 0;\n  padding-bottom: 0;\n  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25);\n  z-index: 1; /* Need this to see the box-shadow on the home page. */\n}\n\nheader .navbar.sub-navbar > .container {\n  padding-left: 26px;\n  padding-right: 26px;\n}\n\nheader .top-left-logo {\n  height: 40px;\n}\n\nheader .top-left-logo-cymbal {\n  height: 30px;\n}\n\nheader .navbar.sub-navbar .navbar-brand {\n  padding: 0;\n}\n\nheader .navbar.sub-navbar a {\n  color: #b4b2bb;\n}\n\nheader .navbar.sub-navbar nav a {\n  margin: 0 10px;\n}\n\nheader .navbar.sub-navbar .controls {\n  display: flex;\n  height: 60px;\n}\n\nheader .navbar.sub-navbar .controls a img {\n  width: 20px;\n  height: 20px;\n  margin-bottom: 3px;\n}\n\n/* Footer */\n\nfooter.py-5 {\n  flex-shrink: 0;\n  padding: 0 !important;\n}\n\nfooter .footer-top {\n  padding: 60px 0px;\n  background-color: #570D2E;\n  color: white;\n}\n\nfooter .footer-top a {\n  color: white;\n  text-decoration: underline;\n}\n\n/* The <p> containing the session-id. */\nfooter .footer-top p:nth-child(3) {\n  margin-top: 56px;\n}\n\nfooter .footer-top .footer-social,\nfooter .footer-top .footer-app,\nfooter .footer-links,\nfooter .footer-top .social,\nfooter .footer-top .app {\n  display: block;\n  align-items: center;\n}\n\nfooter .footer-top .footer-social {\n  padding: 31px;\n}\n\nfooter .footer-top .footer-social h4 {\n  margin-bottom: 0;\n}\n\nfooter .footer-top .footer-social div {\n  width: 50%;\n}\n\n/* Home */\n\nmain {\n  flex: 1 0 auto;\n  background-color: #F9F9F9;\n}\n\n@media (min-width: 992px) {\n  .home .container-fluid {\n    height: calc(100vh - 91px); /* 91px is the height of the top/header bars. */\n  }\n  .home .container-fluid > .row > .col-4 {\n    height: calc(100vh - 91px);\n  }\n  .home .container-fluid > .row > .col-lg-8 {\n    height: calc(100vh - 91px);\n    overflow-y: scroll;\n  }\n}\n\n.home-mobile-hero-banner {\n  height: 200px;\n  background: url(/static/images/folded-clothes-on-white-chair-wide.jpg) no-repeat top center;\n  background-size: cover;\n}\n\n.home-desktop-left-image {\n  background: url(/static/images/folded-clothes-on-white-chair.jpg) no-repeat center;\n  background-size: cover;\n}\n\n.hot-products-row h3 {\n  margin-bottom: 32px;\n  margin-top: 56px;\n  font-size: 36px;\n  font-weight: normal;\n}\n\n.hot-products-row {\n  padding-bottom: 70px;\n  padding-left: 10%;\n  padding-right: 10%;\n}\n\n.hot-product-card  {\n  margin-bottom: 52px;\n  padding-left: 16px;\n  padding-right: 16px;\n}\n\n.hot-product-card img {\n  width: 100%;\n  height: auto;\n  border-radius: 20% 0 20% 20%;\n}\n\n.hot-product-card-name {\n  margin-top: 8px;\n  font-size: 18px;\n}\n\n.hot-product-card-price {\n  font-size: 14px;\n}\n\n.hot-product-card > a:first-child {\n  position: relative;\n  display: block;\n}\n\n.hot-product-card-img-overlay {\n  position: absolute;\n  height: 100%;\n  width: 100%;\n  top: 0;\n  left: 0;\n  border-radius: 20% 0 20% 20%;\n  background-color: transparent;\n}\n\n.hot-product-card:hover .hot-product-card-img-overlay {\n  background-color: rgba(71, 0, 29, 0.2);\n}\n\n/*\nThis chunk ensures the left/right padding of the footer is\nsimilar to that of the hot-products-row.\n*/\n.home-desktop-footer-row {\n  padding-left: 9%;\n  padding-right: 9%;\n  background-color: #570D2E;\n}\n\n/* Ad */\n\n.ad {\n  position: relative;\n  background-color: #FF9A9B;\n  font-size: 24px;\n  text-align: center;\n}\n\n/* \"Ad\" text. */\n.ad strong {\n  position: absolute;\n  top: 6px;\n  left: 12px;\n  font-size: 14px;\n  font-weight: normal;\n}\n\n.ad a {\n  color: black;\n}\n\n/* Product */\n\n.h-product {\n  margin-top: 56px;\n  margin-bottom: 112px;\n  max-width: 1200px;\n  background-color: #F9F9F9;\n}\n\n.h-product > .row {\n  align-items: flex-end;\n}\n\n.h-product .product-image {\n  width: 100%;\n  border-radius: 20% 20% 0 20%;\n}\n\n.h-product .product-price {\n  font-size: 28px;\n}\n\n.h-product .product-info .product-wrapper {\n  margin-left: 15px;\n}\n\n.h-product .product-info h2 {\n  margin-bottom: 16px;\n  margin-top: 16px;\n  font-size: 56px;\n  line-height: 1.14;\n  font-weight: normal;\n  color: #111111;\n}\n\n.h-product .input-group-text,\n.h-product .btn.btn-info {\n  font-size: 18px;\n  line-height: 1.89;\n  letter-spacing: 3.6px;\n  text-align: center;\n  color: #111111;\n  border-radius: 0;\n}\n\n.product-quantity-dropdown {\n  position: relative;\n  width: 100px;\n}\n\n.product-quantity-dropdown select {\n  width: 100%;\n  height: 45px;\n  border: 1px solid #acacac;\n  padding: 10px 16px;\n  border-radius: 8px;\n}\n\n.product-quantity-dropdown img {\n  position: absolute;\n  right: 25px;\n  top: 20px;\n  width: 10px;\n  height: 5px;\n}\n\n.h-product .cymbal-button-primary {\n  margin-top: 16px;\n}\n\n/* Platform Banner */\n\n.local,\n.aws-platform,\n.onprem-platform,\n.azure-platform,\n.alibaba-platform,\n.gcp-platform {\n  position: fixed;\n  top: 0;\n  left: 0;\n  width: 10px;\n  height: 100vh;\n  color: white;\n  font-size: 24px;\n  z-index: 999;\n}\n\n.aws-platform,\n.aws-platform .platform-flag {\n  background-color: #ff9900;\n}\n\n.onprem-platform,\n.onprem-platform .platform-flag {\n  background-color: #34A853;\n}\n\n.gcp-platform,\n.gcp-platform .platform-flag {\n  background-color: #4285f4;\n}\n\n\n.azure-platform,\n.azure-platform .platform-flag {\n  background-color: #f35426;\n}\n\n.alibaba-platform,\n.alibaba-platform .platform-flag {\n  background-color: #ffC300;\n}\n\n.local,\n.local .platform-flag {\n  background-color: #2c0678;\n}\n\n.platform-flag {\n  position: absolute;\n  top: 98px;\n  left: 0;\n  width: 190px;\n  height: 50px;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\n/* Recommendation */\n\n.recommendations {\n  background: #F9F9F9;\n  padding-bottom: 55px;\n}\n\n.recommendations .container {\n  max-width: 1174px;\n}\n\n@media (max-width: 992px) {\n  .recommendations .container {\n    max-width: none;\n  }\n}\n\n.recommendations h2 {\n  border-top: solid 1px;\n  padding: 40px 0;\n  font-weight: normal;\n  text-align: center;\n}\n\n.recommendations h5 {\n  margin-top: 8px;\n  font-weight: normal;\n  font-size: 18px;\n}\n\n.recommendations img {\n  height: 100%;\n  width: 100%;\n  border-radius: 20% 0 20% 20%;\n}\n\nselect {\n  -webkit-appearance: none;\n  -webkit-border-radius: 0px;\n}\n\n/* Cymbal */\n\n/*\nIf we ever decide to create a separate Cymbal CSS library for Cymbal components,\nthe rules below could be extracted.\n*/\n\n.cymbal-button-primary, .cymbal-button-secondary {\n  display: inline-block;\n  border: solid 1px #CE0631;\n  padding: 8px 16px;\n  outline: none;\n  font-size: 14px;\n  border-radius: 22px;\n  cursor: pointer;\n}\n\n.cymbal-button-primary:focus, .cymbal-button-secondary:focus {\n  outline: none; /* To override browser (Chrome) default blue outline. */\n}\n\n.cymbal-button-primary {\n  background-color: #CE0631;\n  color: white;\n}\n\n.cymbal-button-secondary {\n  background: none;\n  color: #CE0631;\n}\n\n.cymbal-form-field {\n  position: relative;\n  margin-top: 24px;\n}\n\n.cymbal-form-field label {\n  width: 100%;\n  margin: 0;\n  padding: 8px 16px 0 16px;\n  font-size: 12px;\n  line-height: 1.8em; /* Without this, there might be a 1px gap underneath. */\n  font-weight: normal;\n  border-radius: 4px 4px 0px 0px;\n  color: #5C6063;\n  background-color: white;\n}\n\n.cymbal-form-field input[type='email'],\n.cymbal-form-field input[type='password'],\n.cymbal-form-field select,\n.cymbal-form-field input[type='text'] {\n  width: 100%;\n  border: none;\n  border-bottom: 1px solid #9AA0A6;\n  padding: 0 16px 8px 16px;\n  outline: none;\n  color: #1E2021;\n}\n\n.cymbal-form-field .cymbal-dropdown-chevron {\n  position: absolute;\n  right: 25px;\n  width: 10px;\n  height: 5px;\n}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/ad.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"text_ad\" }}\n<div class=\"container py-3 px-lg-5 py-lg-5\">\n    <div role=\"alert\">\n        <strong>Ad</strong>\n        <a href=\"{{.RedirectUrl}}\" rel=\"nofollow\" target=\"_blank\">\n            {{.Text}}\n        </a>\n    </div>\n</div>\n{{ end }}"
  },
  {
    "path": "microservices-demo/src/frontend/templates/cart.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"cart\" }}\n    {{ template \"header\" . }}\n    \n    <div {{ with $.platform_css }} class=\"{{.}}\" {{ end }}>\n        <span class=\"platform-flag\">\n            {{$.platform_name}}\n        </span>\n    </div>\n    \n    <main role=\"main\" class=\"cart-sections\">\n\n        {{ if eq (len $.items) 0 }}\n        <section class=\"empty-cart-section\">\n            <h3>Your shopping cart is empty!</h3>\n            <p>Items you add to your shopping cart will appear here.</p>\n            <a class=\"cymbal-button-primary\" href=\"/\" role=\"button\">Continue Shopping</a>\n        </section>\n        {{ else }}\n        <section class=\"container\">\n            <div class=\"row\">\n\n                <div class=\"col-lg-6 col-xl-5 offset-xl-1 cart-summary-section\">\n\n                    <div class=\"row mb-3 py-2\">\n                        <div class=\"col-4 pl-md-0\">\n                            <h3>Cart ({{ $.cart_size }})</h3>\n                        </div>\n                        <div class=\"col-8 pr-md-0 text-right\">\n                            <form method=\"POST\" action=\"/cart/empty\">\n                                <button class=\"cymbal-button-secondary cart-summary-empty-cart-button\" type=\"submit\">\n                                    Empty Cart\n                                </button>\n                                <a class=\"cymbal-button-primary\" href=\"/\" role=\"button\">\n                                    Continue Shopping\n                                </a>\n                            </form>\n                        </div>\n                    </div>\n\n                    {{ range $.items }}\n                    <div class=\"row cart-summary-item-row\">\n                        <div class=\"col-md-4 pl-md-0\">\n                            <a href=\"/product/{{.Item.Id}}\">\n                                <img class=\"img-fluid\" alt=\"\" src=\"{{.Item.Picture}}\" />\n                            </a>\n                        </div>\n                        <div class=\"col-md-8 pr-md-0\">\n                            <div class=\"row\">\n                                <div class=\"col\">\n                                    <h4>{{ .Item.Name }}</h4>\n                                </div>\n                            </div>\n                            <div class=\"row cart-summary-item-row-item-id-row\">\n                                <div class=\"col\">\n                                    SKU #{{ .Item.Id }}\n                                </div>\n                            </div>\n                            <div class=\"row\">\n                                <div class=\"col\">\n                                    Quantity: {{ .Quantity }}\n                                </div>\n                                <div class=\"col pr-md-0 text-right\">\n                                    <strong>\n                                        {{ renderMoney .Price }}\n                                    </strong>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                    {{ end }}\n\n                    <div class=\"row cart-summary-shipping-row\">\n                        <div class=\"col pl-md-0\">Shipping</div>\n                        <div class=\"col pr-md-0 text-right\">{{ renderMoney .shipping_cost }}</div>\n                    </div>\n\n                    <div class=\"row cart-summary-total-row\">\n                        <div class=\"col pl-md-0\">Total</div>\n                        <div class=\"col pr-md-0 text-right\">{{ renderMoney .total_cost }}</div>\n                    </div>\n\n                </div>\n\n                <div class=\"col-lg-5 offset-lg-1 col-xl-4\">\n\n                    <form class=\"cart-checkout-form\" action=\"/cart/checkout\" method=\"POST\">\n\n                        <div class=\"row\">\n                            <div class=\"col\">\n                                <h3>Shipping Address</h3>\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col cymbal-form-field\">\n                                <label for=\"email\">E-mail Address</label>\n                                <input type=\"email\" id=\"email\"\n                                    name=\"email\" value=\"someone@example.com\" required>\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col cymbal-form-field\">\n                                <label for=\"street_address\">Street Address</label>\n                                <input type=\"text\" name=\"street_address\"\n                                    id=\"street_address\" value=\"1600 Amphitheatre Parkway\" required>\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col cymbal-form-field\">\n                                <label for=\"zip_code\">Zip Code</label>\n                                <input type=\"text\"\n                                    name=\"zip_code\" id=\"zip_code\" value=\"94043\" required pattern=\"\\d{4,5}\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col cymbal-form-field\">\n                                <label for=\"city\">City</label>\n                                <input type=\"text\" name=\"city\" id=\"city\"\n                                    value=\"Mountain View\" required>\n                                </div>\n                            </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col-md-5 cymbal-form-field\">\n                                <label for=\"state\">State</label>\n                                <input type=\"text\" name=\"state\" id=\"state\"\n                                    value=\"CA\" required>\n                            </div>\n                            <div class=\"col-md-7 cymbal-form-field\">\n                                <label for=\"country\">Country</label>\n                                <input type=\"text\" id=\"country\"\n                                    placeholder=\"Country Name\"\n                                    name=\"country\" value=\"United States\" required>\n                            </div>\n                        </div>\n\n                        <div class=\"row\">\n                            <div class=\"col\">\n                                <h3 class=\"payment-method-heading\">Payment Method</h3>\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col cymbal-form-field\">\n                                <label for=\"credit_card_number\">Credit Card Number</label>\n                                <input type=\"text\" id=\"credit_card_number\"\n                                    name=\"credit_card_number\"\n                                    placeholder=\"0000-0000-0000-0000\"\n                                    value=\"4432-8015-6152-0454\"\n                                    required pattern=\"\\d{4}-\\d{4}-\\d{4}-\\d{4}\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-row\">\n                            <div class=\"col-md-5 cymbal-form-field\">\n                                <label for=\"credit_card_expiration_month\">Month</label>\n                                <select name=\"credit_card_expiration_month\" id=\"credit_card_expiration_month\">\n                                    <option value=\"1\">January</option>\n                                    <option value=\"2\">February</option>\n                                    <option value=\"3\">March</option>\n                                    <option value=\"4\">April</option>\n                                    <option value=\"5\">May</option>\n                                    <option value=\"6\">June</option>\n                                    <option value=\"7\">July</option>\n                                    <option value=\"8\">August</option>\n                                    <option value=\"9\">September</option>\n                                    <option value=\"10\">October</option>\n                                    <option value=\"11\">November</option>\n                                    <option value=\"12\">January</option>\n                                </select>\n                                <img src=\"/static/icons/Hipster_DownArrow.svg\" alt=\"\" class=\"cymbal-dropdown-chevron\">\n                            </div>\n                            <div class=\"col-md-4 cymbal-form-field\">\n                                    <label for=\"credit_card_expiration_year\">Year</label>\n                                    <select name=\"credit_card_expiration_year\" id=\"credit_card_expiration_year\">\n                                    {{ range $i, $y := $.expiration_years}}<option value=\"{{$y}}\"\n                                        {{if eq $i 1 -}}\n                                            selected=\"selected\"\n                                        {{- end}}\n                                    >{{$y}}</option>{{end}}\n                                    </select>\n                                    <img src=\"/static/icons/Hipster_DownArrow.svg\" alt=\"\" class=\"cymbal-dropdown-chevron\">\n                                </div>\n                            <div class=\"col-md-3 cymbal-form-field\">\n                                <label for=\"credit_card_cvv\">CVV</label>\n                                <input type=\"password\" id=\"credit_card_cvv\"\n                                    name=\"credit_card_cvv\" value=\"672\" required pattern=\"\\d{3}\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-row justify-content-center\">\n                            <div class=\"col text-center\">\n                                <button class=\"cymbal-button-primary\" type=\"submit\">\n                                    Place Order\n                                </button>\n                            </div>\n                        </div>\n\n                    </form>\n\n                </div>\n\n            </div>\n        </section>\n        {{ end }} <!-- end if $.items -->\n\n    </main>\n\n    {{ if $.recommendations}}\n        {{ template \"recommendations\" $.recommendations }}\n    {{ end }}\n\n    {{ template \"footer\" . }}\n    {{ end }}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/error.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"error\" }}\n    {{ template \"header\" . }}\n    <div {{ with $.platform_css }} class=\"{{.}}\" {{ end }}>\n        <span class=\"platform-flag\">\n          {{$.platform_name}}\n        </span>\n      </div>\n    <main role=\"main\">\n        <div class=\"py-5\">\n            <div class=\"container bg-light py-3 px-lg-5 py-lg-5\">\n                <h1>Uh, oh!</h1>\n                <p>Something has failed. Below are some details for debugging.</p>\n\n                <p><strong>HTTP Status:</strong> {{.status_code}} {{.status}}</p>\n                <pre class=\"border border-danger p-3\"\n                    style=\"white-space: pre-wrap; word-break: keep-all;\">\n                    {{- .error -}}\n                </pre>\n            </div>\n        </div>\n    </main>\n\n    {{ template \"footer\" . }}\n    {{ end }}"
  },
  {
    "path": "microservices-demo/src/frontend/templates/footer.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"footer\" }}\n\n<footer class=\"py-5\">\n    <div class=\"footer-top\">\n        <div class=\"container footer-social\">\n            <p class=\"footer-text\">This website is hosted for demo purposes only. It is not an actual shop. This is not a Google product.</p>\n            <p class=\"footer-text\">© 2020 Google Inc (<a href=\"https://github.com/GoogleCloudPlatform/microservices-demo\">Source Code</a>)</p>\n            <p class=\"footer-text\">\n                <small>\n                    {{ if $.session_id }}session-id: {{ $.session_id }} — {{end}}\n                    {{ if $.request_id }}request-id: {{ $.request_id }}{{end}}\n                </small>\n                <br/>\n                <small>\n                    {{ if $.deploymentDetails }}\n                        {{ if index .deploymentDetails \"CLUSTERNAME\" }}\n                        <b>Cluster: </b>{{ index .deploymentDetails \"CLUSTERNAME\" }}<br/>\n                        {{ end }}\n                        {{ if index .deploymentDetails \"ZONE\" }}\n                        <b>Zone: </b>{{ index .deploymentDetails \"ZONE\" }}<br/>\n                        {{ end }}\n                        {{ if index .deploymentDetails \"HOSTNAME\" }}\n                        <b>Pod: </b>{{ index .deploymentDetails \"HOSTNAME\" }}\n                        {{ end }}\n                    {{ else }}\n                    Deployment details are still loading.\n                    Try refreshing this page.\n                    {{ end }}\n                </small>\n            </p>\n        </div>\n    </div>\n</footer>\n<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js\"\n    integrity=\"sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T\" crossorigin=\"anonymous\">\n</script>\n</body>\n\n</html>\n{{ end }}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/header.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"header\" }}\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, shrink-to-fit=no\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"ie=edge\">\n    <title>\n        {{ if $.is_cymbal_brand }}\n        Cymbal Shops\n        {{ else }}\n        Online Boutique\n        {{ end }}\n    </title>\n    <link href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB\"\n        crossorigin=\"anonymous\">\n    <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n    <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n    <link href=\"https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap\" rel=\"stylesheet\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/static/styles/styles.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/static/styles/cart.css\">\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"/static/styles/order.css\">\n    {{ if $.is_cymbal_brand }}\n    <link rel='shortcut icon' type='image/x-icon' href='/static/favicon-cymbal.ico' />\n    {{ else }}\n    <link rel='shortcut icon' type='image/x-icon' href='/static/favicon.ico' />\n    {{ end }}\n</head>\n\n<body>\n    <header>\n        <div class=\"navbar sub-navbar\">\n            <div class=\"container d-flex justify-content-between\">\n                <a href=\"/\" class=\"navbar-brand d-flex align-items-center\">\n                    {{ if $.is_cymbal_brand }}\n                    <img src=\"/static/icons/Cymbal_NavLogo.svg\" alt=\"\" class=\"top-left-logo-cymbal\" />\n                    {{ else }}\n                    <img src=\"/static/icons/Hipster_NavLogo.svg\" alt=\"\" class=\"top-left-logo\" />\n                    {{ end }}\n                </a>\n                <div class=\"controls\">\n\n                    {{ if $.show_currency }}\n                    <div class=\"h-controls\">\n                        <div class=\"h-control\">\n                            <span class=\"icon currency-icon\"> {{ renderCurrencyLogo $.user_currency}}</span>\n                            <form method=\"POST\" class=\"controls-form\" action=\"/setCurrency\" id=\"currency_form\" >\n                                <select name=\"currency_code\" onchange=\"document.getElementById('currency_form').submit();\">\n                                        {{range $.currencies}}\n                                    <option value=\"{{.}}\" {{if eq . $.user_currency}}selected=\"selected\"{{end}}>{{.}}</option>\n                                    {{end}}\n                                </select>\n                            </form>\n                            <img src=\"/static/icons/Hipster_DownArrow.svg\" alt=\"\" class=\"icon arrow\" />\n                        </div>\n                    </div>\n                    {{ end }}\n\n                    <a href=\"/cart\" class=\"cart-link\">\n                        <img src=\"/static/icons/Hipster_CartIcon.svg\" alt=\"Cart icon\" class=\"logo\" title=\"Cart\" />\n                        {{ if $.cart_size }}\n                        <span class=\"cart-size-circle\">{{$.cart_size}}</span>\n                        {{ end }}\n                    </a>\n                </div>\n            </div>\n        </div>\n\n    </header>\n    {{end}}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/home.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"home\" }}\n\n{{ template \"header\" . }}\n<div {{ with $.platform_css }} class=\"{{.}}\" {{ end }}>\n  <span class=\"platform-flag\">\n    {{$.platform_name}}\n  </span>\n</div>\n<main role=\"main\" class=\"home\">\n\n  <!-- The image at the top of the home page, displayed on smaller screens. -->\n  <div class=\"home-mobile-hero-banner d-lg-none\"></div>\n\n  <div class=\"container-fluid\">\n    <div class=\"row\">\n\n      <!-- The image on the left of the home page, displayed on larger screens. -->\n      <div class=\"col-4 d-none d-lg-block home-desktop-left-image\"></div>\n\n      <div class=\"col-12 col-lg-8\">\n\n        <div class=\"row hot-products-row px-xl-6\">\n\n          <div class=\"col-12\">\n            <h3>Hot Products</h3>\n          </div>\n\n          {{ range $.products }}\n          <div class=\"col-md-4 hot-product-card\">\n            <a href=\"/product/{{.Item.Id}}\">\n              <img alt=\"\" src=\"{{.Item.Picture}}\">\n              <div class=\"hot-product-card-img-overlay\"></div>\n            </a>\n            <div>\n              <div class=\"hot-product-card-name\">{{ .Item.Name }}</div>\n              <div class=\"hot-product-card-price\">{{ renderMoney .Price }}</div>\n            </div>\n          </div>\n          {{ end }}\n\n        </div>\n\n        <!-- Footer for larger screens. -->\n        <div class=\"row d-none d-lg-block home-desktop-footer-row\">\n          <div class=\"col-12 p-0\">\n            {{ template \"footer\" . }}\n          </div>\n        </div>\n\n      </div>\n\n    </div>\n  </div>\n\n</main>\n\n<!-- Footer for smaller screens. -->\n<div class=\"d-lg-none\">\n  {{ template \"footer\" . }}\n</div>\n\n{{ end }}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/order.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"order\" }}\n\n    {{ template \"header\" . }}\n\n    <div {{ with $.platform_css }} class=\"{{.}}\" {{ end }}>\n        <span class=\"platform-flag\">\n            {{$.platform_name}}\n        </span>\n    </div>\n\n    <main role=\"main\" class=\"order\">\n\n        <section class=\"container order-complete-section\">\n            <div class=\"row\">\n                <div class=\"col-12 text-center\">\n                    <h3>\n                        Your order is complete!\n                    </h3>\n                </div>\n                <div class=\"col-12 text-center\">\n                    <p>We've sent you a confirmation email.</p>\n                </div>\n            </div>\n            <div class=\"row border-bottom-solid padding-y-24\">\n                <div class=\"col-6 pl-md-0\">\n                    Confirmation #\n                </div>\n                <div class=\"col-6 pr-md-0 text-right\">\n                    {{.order.OrderId}}\n                </div>\n            </div>\n            <div class=\"row border-bottom-solid padding-y-24\">\n                <div class=\"col-6 pl-md-0\">\n                    Tracking #\n                </div>\n                <div class=\"col-6 pr-md-0 text-right\">\n                    {{.order.ShippingTrackingId}}\n                </div>\n            </div>\n            <div class=\"row padding-y-24\">\n                <div class=\"col-6 pl-md-0\">\n                    Total Paid\n                </div>\n                <div class=\"col-6 pr-md-0 text-right\">\n                    {{renderMoney .total_paid}}\n                </div>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-12 text-center\">\n                    <a class=\"cymbal-button-primary\" href=\"/\" role=\"button\">\n                        Continue Shopping\n                    </a>\n                </div>\n            </div>\n        </section>\n\n        {{ if $.recommendations }}\n            {{ template \"recommendations\" $.recommendations }}\n        {{ end }}\n\n    </main>\n\n    {{ template \"footer\" . }}\n    {{ end }}\n"
  },
  {
    "path": "microservices-demo/src/frontend/templates/product.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"product\" }}\n{{ template \"header\" . }}\n<div {{ with $.platform_css }} class=\"{{.}}\" {{ end }}>\n  <span class=\"platform-flag\">\n    {{$.platform_name}}\n  </span>\n</div>\n\n<main role=\"main\">\n  <div class=\"h-product container\">\n    <div class=\"row\">\n      <div class=\"col-md-6\">\n        <img class=\"product-image\" alt=\"\" src=\"{{$.product.Item.Picture}}\" />\n      </div>\n      <div class=\"product-info col-md-5\">\n        <div class=\"product-wrapper\">\n\n          <h2>{{ $.product.Item.Name }}</h2>\n          <p class=\"product-price\">{{ renderMoney $.product.Price }}</p>\n          <p>{{ $.product.Item.Description }}</p>\n\n          <form method=\"POST\" action=\"/cart\">\n            <input type=\"hidden\" name=\"product_id\" value=\"{{$.product.Item.Id}}\" />\n            <div class=\"product-quantity-dropdown\">\n              <select name=\"quantity\" id=\"quantity\">\n                <option>1</option>\n                <option>2</option>\n                <option>3</option>\n                <option>4</option>\n                <option>5</option>\n                <option>10</option>\n              </select>\n              <img src=\"/static/icons/Hipster_DownArrow.svg\" alt=\"\">\n            </div>\n            <button type=\"submit\" class=\"cymbal-button-primary\">Add To Cart</button>\n          </form>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div>\n    {{ if $.recommendations}}\n      {{ template \"recommendations\" $.recommendations }}\n    {{ end }}\n  </div>\n  <div class=\"ad\">\n   {{ with $.ad }}{{ template \"text_ad\" . }}{{ end }}\n  </div>\n</main>\n{{ template \"footer\" . }}\n{{ end }}"
  },
  {
    "path": "microservices-demo/src/frontend/templates/recommendations.html",
    "content": "<!--\n Copyright 2020 Google LLC\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n      http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n-->\n\n{{ define \"recommendations\" }}\n<section class=\"recommendations\">\n    <div class=\"container\">\n      <div class=\"row\">\n        <div class=\"col-xl-10 offset-xl-1\">\n          <h2>You May Also Like</h2>\n          <div class=\"row\">\n            {{range . }}\n            <div class=\"col-md-3\">\n              <div>\n                <a href=\"/product/{{.Id}}\">\n                  <img alt=\"\" src=\"{{.Picture}}\">\n                </a>\n                <div>\n                  <h5>\n                    {{ .Name }}\n                  </h5>\n                </div>\n              </div>\n            </div>\n            {{ end }}\n          </div>\n        </div>\n      </div>\n    </div>\n</section>\n{{ end }}"
  },
  {
    "path": "microservices-demo/src/loadgenerator/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM python:3.9-slim as base\n\nFROM base as builder\n\nRUN apt-get -qq update \\\n    && apt-get install -y --no-install-recommends \\\n        g++\n\nCOPY requirements.txt .\n\nRUN pip install --prefix=\"/install\" -r requirements.txt\n\nFROM base\n\nWORKDIR /loadgen\n\nCOPY --from=builder /install /usr/local\n\n# Add application code.\nCOPY locustfile.py .\n\n# enable gevent support in debugger\nENV GEVENT_SUPPORT=True\n\nENTRYPOINT locust --host=\"http://${FRONTEND_ADDR}\" --headless -u \"${USERS:-10}\" 2>&1\n"
  },
  {
    "path": "microservices-demo/src/loadgenerator/loadgenerator.yaml",
    "content": "# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: loadgenerator\nspec:\n  selector:\n    matchLabels:\n      app: loadgenerator\n  replicas: 1\n  template:\n    metadata:\n      labels:\n        app: loadgenerator\n      annotations:\n        sidecar.istio.io/rewriteAppHTTPProbers: \"true\"\n    spec:\n      serviceAccountName: default\n      terminationGracePeriodSeconds: 5\n      restartPolicy: Always\n      securityContext:\n        fsGroup: 1000\n        runAsGroup: 1000\n        runAsNonRoot: true\n        runAsUser: 1000\n      initContainers:\n      - command:\n        - /bin/sh\n        - -exc\n        - |\n          echo \"Init container pinging frontend: ${FRONTEND_ADDR}...\"\n          STATUSCODE=$(wget --server-response http://${FRONTEND_ADDR} 2>&1 | awk '/^  HTTP/{print $2}')\n          if test $STATUSCODE -ne 200; then\n              echo \"Error: Could not reach frontend - Status code: ${STATUSCODE}\"\n              exit 1\n          fi\n        name: frontend-check\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n              - all\n          privileged: false\n          readOnlyRootFilesystem: true\n        image: busybox:latest\n        env:\n        - name: FRONTEND_ADDR\n          value: \"frontend:80\"\n      containers:\n      - name: main\n        securityContext:\n          allowPrivilegeEscalation: false\n          capabilities:\n            drop:\n              - all\n          privileged: false\n          readOnlyRootFilesystem: true\n        image: <LOAD_GENERATOR_IMAGE>\n        env:\n        - name: FRONTEND_ADDR\n          value: \"frontend:80\"\n        - name: USERS\n          value: \"10\"\n        resources:\n          requests:\n            cpu: 300m\n            memory: 256Mi\n          limits:\n            cpu: 500m\n            memory: 512Mi\n"
  },
  {
    "path": "microservices-demo/src/loadgenerator/locustfile.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport random\nfrom locust import HttpUser, TaskSet, between\n\nproducts = [\n    '0PUK6V6EV0',\n    '1YMWWN1N4O',\n    '2ZYFJ3GM2N',\n    '66VCHSJNUP',\n    '6E92ZMYYFZ',\n    '9SIQT8TOJO',\n    'L9ECAV7KIM',\n    'LS4PSXUNUM',\n    'OLJCESPC7Z']\n\ndef index(l):\n    l.client.get(\"/\")\n\ndef setCurrency(l):\n    currencies = ['EUR', 'USD', 'JPY', 'CAD']\n    l.client.post(\"/setCurrency\",\n        {'currency_code': random.choice(currencies)})\n\ndef browseProduct(l):\n    l.client.get(\"/product/\" + random.choice(products))\n\ndef viewCart(l):\n    l.client.get(\"/cart\")\n\ndef addToCart(l):\n    product = random.choice(products)\n    l.client.get(\"/product/\" + product)\n    l.client.post(\"/cart\", {\n        'product_id': product,\n        'quantity': random.choice([1,2,3,4,5,10])})\n\ndef checkout(l):\n    addToCart(l)\n    l.client.post(\"/cart/checkout\", {\n        'email': 'someone@example.com',\n        'street_address': '1600 Amphitheatre Parkway',\n        'zip_code': '94043',\n        'city': 'Mountain View',\n        'state': 'CA',\n        'country': 'United States',\n        'credit_card_number': '4432-8015-6152-0454',\n        'credit_card_expiration_month': '1',\n        'credit_card_expiration_year': '2039',\n        'credit_card_cvv': '672',\n    })\n\nclass UserBehavior(TaskSet):\n\n    def on_start(self):\n        index(self)\n\n    tasks = {index: 1,\n        setCurrency: 2,\n        browseProduct: 10,\n        addToCart: 2,\n        viewCart: 3,\n        checkout: 1}\n\nclass WebsiteUser(HttpUser):\n    tasks = [UserBehavior]\n    wait_time = between(1, 10)\n"
  },
  {
    "path": "microservices-demo/src/loadgenerator/requirements.in",
    "content": "locust==2.12.1\n"
  },
  {
    "path": "microservices-demo/src/loadgenerator/requirements.txt",
    "content": "#\n# This file is autogenerated by pip-compile with python 3.9\n# To update, run:\n#\n#    pip-compile --output-file=requirements.txt requirements.in\n#\nbrotli==1.0.9\n    # via geventhttpclient\ncertifi==2022.9.24\n    # via\n    #   geventhttpclient\n    #   requests\ncharset-normalizer==2.1.1\n    # via requests\nclick==8.1.3\n    # via flask\nconfigargparse==1.5.3\n    # via locust\nflask==2.2.2\n    # via\n    #   flask-basicauth\n    #   flask-cors\n    #   locust\nflask-basicauth==0.2.0\n    # via locust\nflask-cors==3.0.10\n    # via locust\ngevent==21.12.0\n    # via\n    #   geventhttpclient\n    #   locust\ngeventhttpclient==2.0.2\n    # via locust\ngreenlet==1.1.3\n    # via gevent\nidna==3.4\n    # via requests\nimportlib-metadata==5.0.0\n    # via flask\nitsdangerous==2.1.2\n    # via flask\njinja2==3.1.2\n    # via flask\nlocust==2.12.1\n    # via -r requirements.in\nmarkupsafe==2.1.1\n    # via\n    #   jinja2\n    #   werkzeug\nmsgpack==1.0.4\n    # via locust\npsutil==5.9.2\n    # via locust\npyzmq==24.0.1\n    # via locust\nrequests==2.28.1\n    # via locust\nroundrobin==0.0.4\n    # via locust\nsix==1.16.0\n    # via\n    #   flask-cors\n    #   geventhttpclient\ntyping-extensions==4.3.0\n    # via locust\nurllib3==1.26.12\n    # via requests\nwerkzeug==2.2.2\n    # via\n    #   flask\n    #   locust\nzipp==3.8.1\n    # via importlib-metadata\nzope-event==4.5.0\n    # via gevent\nzope-interface==5.4.0\n    # via gevent\n\n# The following packages are considered to be unsafe in a requirements file:\n# setuptools\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/.dockerignore",
    "content": "node_modules\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/.gitignore",
    "content": "node_modules\n.DS_Store\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM node:18-alpine as base\n\nFROM base as builder\n\n# Some packages (e.g. @google-cloud/profiler) require additional\n# deps for post-install scripts\nRUN apk add --update --no-cache \\\n    python3 \\\n    make \\\n    g++ \n\nWORKDIR /usr/src/app\n\nCOPY package*.json ./\n\nRUN npm install --only=production\n\nFROM base\n\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\n\nWORKDIR /usr/src/app\n\nCOPY --from=builder /usr/src/app/node_modules ./node_modules\n\nCOPY . .\n\nEXPOSE 50051\n\nENTRYPOINT [ \"node\", \"index.js\" ]\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/charge.js",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nconst cardValidator = require('simple-card-validator');\nconst uuid = require('uuid/v4');\nconst pino = require('pino');\n\nconst logger = pino({\n  name: 'paymentservice-charge',\n  messageKey: 'message',\n  changeLevelName: 'severity',\n  useLevelLabels: true\n});\n\n\nclass CreditCardError extends Error {\n  constructor (message) {\n    super(message);\n    this.code = 400; // Invalid argument error\n  }\n}\n\nclass InvalidCreditCard extends CreditCardError {\n  constructor (cardType) {\n    super(`Credit card info is invalid`);\n  }\n}\n\nclass UnacceptedCreditCard extends CreditCardError {\n  constructor (cardType) {\n    super(`Sorry, we cannot process ${cardType} credit cards. Only VISA or MasterCard is accepted.`);\n  }\n}\n\nclass ExpiredCreditCard extends CreditCardError {\n  constructor (number, month, year) {\n    super(`Your credit card (ending ${number.substr(-4)}) expired on ${month}/${year}`);\n  }\n}\n\n/**\n * Verifies the credit card number and (pretend) charges the card.\n *\n * @param {*} request\n * @return transaction_id - a random uuid v4.\n */\nmodule.exports = function charge (request) {\n  const { amount, credit_card: creditCard } = request;\n  const cardNumber = creditCard.credit_card_number;\n  const cardInfo = cardValidator(cardNumber);\n  const {\n    card_type: cardType,\n    valid\n  } = cardInfo.getCardDetails();\n\n  if (!valid) { throw new InvalidCreditCard(); }\n\n  // Only VISA and mastercard is accepted, other card types (AMEX, dinersclub) will\n  // throw UnacceptedCreditCard error.\n  if (!(cardType === 'visa' || cardType === 'mastercard')) { throw new UnacceptedCreditCard(cardType); }\n\n  // Also validate expiration is > today.\n  const currentMonth = new Date().getMonth() + 1;\n  const currentYear = new Date().getFullYear();\n  const { credit_card_expiration_year: year, credit_card_expiration_month: month } = creditCard;\n  if ((currentYear * 12 + currentMonth) > (year * 12 + month)) { throw new ExpiredCreditCard(cardNumber.replace('-', ''), month, year); }\n\n  logger.info(`Transaction processed: ${cardType} ending ${cardNumber.substr(-4)} \\\n    Amount: ${amount.currency_code}${amount.units}.${amount.nanos}`);\n\n  return { transaction_id: uuid() };\n};\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_paymentservice_genproto]\n\n# protos are loaded dynamically for node, simply copies over the proto.\nmkdir -p proto\ncp -r ../../pb/* ./proto\n\n# [END gke_paymentservice_genproto]"
  },
  {
    "path": "microservices-demo/src/paymentservice/index.js",
    "content": "/*\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n'use strict';\n\n\nif(process.env.DISABLE_PROFILER) {\n  console.log(\"Profiler disabled.\")\n}\nelse {\n  console.log(\"Profiler enabled.\")\n  require('@google-cloud/profiler').start({\n    serviceContext: {\n      service: 'paymentservice',\n      version: '1.0.0'\n    }\n  });\n}\n\n\nif(process.env.DISABLE_TRACING) {\n  console.log(\"Tracing disabled.\")\n}\nelse {\n  console.log(\"Tracing enabled.\")\n  require('@google-cloud/trace-agent').start();\n\n}\n\nif(process.env.DISABLE_DEBUGGER) {\n  console.log(\"Debugger disabled.\")\n}\nelse {\n  console.log(\"Debugger enabled.\")\n  require('@google-cloud/debug-agent').start({\n    serviceContext: {\n      service: 'paymentservice',\n      version: 'VERSION'\n    }\n  });\n}\n\n\nconst path = require('path');\nconst HipsterShopServer = require('./server');\n\nconst PORT = process.env['PORT'];\nconst PROTO_PATH = path.join(__dirname, '/proto/');\n\nconst server = new HipsterShopServer(PROTO_PATH, PORT);\n\nserver.listen();\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/package.json",
    "content": "{\n  \"name\": \"paymentservice\",\n  \"version\": \"0.0.1\",\n  \"description\": \"Payment Microservice demo\",\n  \"repository\": \"https://github.com/GoogleCloudPlatform/microservices-demo\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Warn: no test specified\\\" && exit 0\",\n    \"lint\": \"semistandard *.js\"\n  },\n  \"author\": \"Jonathan Lui\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"@google-cloud/debug-agent\": \"5.2.9\",\n    \"@google-cloud/profiler\": \"4.2.0\",\n    \"@google-cloud/trace-agent\": \"5.1.6\",\n    \"@grpc/grpc-js\": \"1.6.11\",\n    \"@grpc/proto-loader\": \"0.6.13\",\n    \"pino\": \"5.17.0\",\n    \"simple-card-validator\": \"^1.1.0\",\n    \"uuid\": \"^3.2.1\"\n  },\n  \"devDependencies\": {\n    \"semistandard\": \"16.0.1\"\n  }\n}\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/proto/demo.proto",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\npackage hipstershop;\n\n// -----------------Cart service-----------------\n\nservice CartService {\n    rpc AddItem(AddItemRequest) returns (Empty) {}\n    rpc GetCart(GetCartRequest) returns (Cart) {}\n    rpc EmptyCart(EmptyCartRequest) returns (Empty) {}\n}\n\nmessage CartItem {\n    string product_id = 1;\n    int32  quantity = 2;\n}\n\nmessage AddItemRequest {\n    string user_id = 1;\n    CartItem item = 2;\n}\n\nmessage EmptyCartRequest {\n    string user_id = 1;\n}\n\nmessage GetCartRequest {\n    string user_id = 1;\n}\n\nmessage Cart {\n    string user_id = 1;\n    repeated CartItem items = 2;\n}\n\nmessage Empty {}\n\n// ---------------Recommendation service----------\n\nservice RecommendationService {\n  rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse){}\n}\n\nmessage ListRecommendationsRequest {\n    string user_id = 1;\n    repeated string product_ids = 2;\n}\n\nmessage ListRecommendationsResponse {\n    repeated string product_ids = 1;\n}\n\n// ---------------Product Catalog----------------\n\nservice ProductCatalogService {\n    rpc ListProducts(Empty) returns (ListProductsResponse) {}\n    rpc GetProduct(GetProductRequest) returns (Product) {}\n    rpc SearchProducts(SearchProductsRequest) returns (SearchProductsResponse) {}\n}\n\nmessage Product {\n    string id = 1;\n    string name = 2;\n    string description = 3;\n    string picture = 4;\n    Money price_usd = 5;\n\n    // Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n    // other related products.\n    repeated string categories = 6;\n}\n\nmessage ListProductsResponse {\n    repeated Product products = 1;\n}\n\nmessage GetProductRequest {\n    string id = 1;\n}\n\nmessage SearchProductsRequest {\n    string query = 1;\n}\n\nmessage SearchProductsResponse {\n    repeated Product results = 1;\n}\n\n// ---------------Shipping Service----------\n\nservice ShippingService {\n    rpc GetQuote(GetQuoteRequest) returns (GetQuoteResponse) {}\n    rpc ShipOrder(ShipOrderRequest) returns (ShipOrderResponse) {}\n}\n\nmessage GetQuoteRequest {\n    Address address = 1;\n    repeated CartItem items = 2;\n}\n\nmessage GetQuoteResponse {\n    Money cost_usd = 1;\n}\n\nmessage ShipOrderRequest {\n    Address address = 1;\n    repeated CartItem items = 2;\n}\n\nmessage ShipOrderResponse {\n    string tracking_id = 1;\n}\n\nmessage Address {\n    string street_address = 1;\n    string city = 2;\n    string state = 3;\n    string country = 4;\n    int32 zip_code = 5;\n}\n\n// -----------------Currency service-----------------\n\nservice CurrencyService {\n    rpc GetSupportedCurrencies(Empty) returns (GetSupportedCurrenciesResponse) {}\n    rpc Convert(CurrencyConversionRequest) returns (Money) {}\n}\n\n// Represents an amount of money with its currency type.\nmessage Money {\n    // The 3-letter currency code defined in ISO 4217.\n    string currency_code = 1;\n\n    // The whole units of the amount.\n    // For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n    int64 units = 2;\n\n    // Number of nano (10^-9) units of the amount.\n    // The value must be between -999,999,999 and +999,999,999 inclusive.\n    // If `units` is positive, `nanos` must be positive or zero.\n    // If `units` is zero, `nanos` can be positive, zero, or negative.\n    // If `units` is negative, `nanos` must be negative or zero.\n    // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n    int32 nanos = 3;\n}\n\nmessage GetSupportedCurrenciesResponse {\n    // The 3-letter currency code defined in ISO 4217.\n    repeated string currency_codes = 1;\n}\n\nmessage CurrencyConversionRequest {\n    Money from = 1;\n\n    // The 3-letter currency code defined in ISO 4217.\n    string to_code = 2;\n}\n\n// -------------Payment service-----------------\n\nservice PaymentService {\n    rpc Charge(ChargeRequest) returns (ChargeResponse) {}\n}\n\nmessage CreditCardInfo {\n    string credit_card_number = 1;\n    int32 credit_card_cvv = 2;\n    int32 credit_card_expiration_year = 3;\n    int32 credit_card_expiration_month = 4;\n}\n\nmessage ChargeRequest {\n    Money amount = 1;\n    CreditCardInfo credit_card = 2;\n}\n\nmessage ChargeResponse {\n    string transaction_id = 1;\n}\n\n// -------------Email service-----------------\n\nservice EmailService {\n    rpc SendOrderConfirmation(SendOrderConfirmationRequest) returns (Empty) {}\n}\n\nmessage OrderItem {\n    CartItem item = 1;\n    Money cost = 2;\n}\n\nmessage OrderResult {\n    string   order_id = 1;\n    string   shipping_tracking_id = 2;\n    Money shipping_cost = 3;\n    Address  shipping_address = 4;\n    repeated OrderItem items = 5;\n}\n\nmessage SendOrderConfirmationRequest {\n    string email = 1;\n    OrderResult order = 2;\n}\n\n\n// -------------Checkout service-----------------\n\nservice CheckoutService {\n    rpc PlaceOrder(PlaceOrderRequest) returns (PlaceOrderResponse) {}\n}\n\nmessage PlaceOrderRequest {\n    string user_id = 1;\n    string user_currency = 2;\n\n    Address address = 3;\n    string email = 5;\n    CreditCardInfo credit_card = 6;\n}\n\nmessage PlaceOrderResponse {\n    OrderResult order = 1;\n}\n\n// ------------Ad service------------------\n\nservice AdService {\n    rpc GetAds(AdRequest) returns (AdResponse) {}\n}\n\nmessage AdRequest {\n    // List of important key words from the current page describing the context.\n    repeated string context_keys = 1;\n}\n\nmessage AdResponse {\n    repeated Ad ads = 1;\n}\n\nmessage Ad {\n    // url to redirect to when an ad is clicked.\n    string redirect_url = 1;\n\n    // short advertisement text to display.\n    string text = 2;\n}\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/proto/grpc/health/v1/health.proto",
    "content": "// Copyright 2015 The gRPC Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// The canonical version of this proto can be found at\n// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto\n\nsyntax = \"proto3\";\n\npackage grpc.health.v1;\n\noption csharp_namespace = \"Grpc.Health.V1\";\noption go_package = \"google.golang.org/grpc/health/grpc_health_v1\";\noption java_multiple_files = true;\noption java_outer_classname = \"HealthProto\";\noption java_package = \"io.grpc.health.v1\";\n\nmessage HealthCheckRequest {\n  string service = 1;\n}\n\nmessage HealthCheckResponse {\n  enum ServingStatus {\n    UNKNOWN = 0;\n    SERVING = 1;\n    NOT_SERVING = 2;\n  }\n  ServingStatus status = 1;\n}\n\nservice Health {\n  rpc Check(HealthCheckRequest) returns (HealthCheckResponse);\n}\n"
  },
  {
    "path": "microservices-demo/src/paymentservice/server.js",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nconst path = require('path');\nconst grpc = require('@grpc/grpc-js');\nconst pino = require('pino');\nconst protoLoader = require('@grpc/proto-loader');\n\nconst charge = require('./charge');\n\nconst logger = pino({\n  name: 'paymentservice-server',\n  messageKey: 'message',\n  changeLevelName: 'severity',\n  useLevelLabels: true\n});\n\nclass HipsterShopServer {\n  constructor(protoRoot, port = HipsterShopServer.PORT) {\n    this.port = port;\n\n    this.packages = {\n      hipsterShop: this.loadProto(path.join(protoRoot, 'demo.proto')),\n      health: this.loadProto(path.join(protoRoot, 'grpc/health/v1/health.proto'))\n    };\n\n    this.server = new grpc.Server();\n    this.loadAllProtos(protoRoot);\n  }\n\n  /**\n   * Handler for PaymentService.Charge.\n   * @param {*} call  { ChargeRequest }\n   * @param {*} callback  fn(err, ChargeResponse)\n   */\n  static ChargeServiceHandler(call, callback) {\n    try {\n      logger.info(`PaymentService#Charge invoked with request ${JSON.stringify(call.request)}`);\n      const response = charge(call.request);\n      callback(null, response);\n    } catch (err) {\n      console.warn(err);\n      callback(err);\n    }\n  }\n\n  static CheckHandler(call, callback) {\n    callback(null, { status: 'SERVING' });\n  }\n\n\n  listen() {\n    const server = this.server \n    const port = this.port\n    server.bindAsync(\n      `0.0.0.0:${port}`,\n      grpc.ServerCredentials.createInsecure(),\n      function () {\n        logger.info(`PaymentService gRPC server started on port ${port}`);\n        server.start();\n      }\n    );\n  }\n\n  loadProto(path) {\n    const packageDefinition = protoLoader.loadSync(\n      path,\n      {\n        keepCase: true,\n        longs: String,\n        enums: String,\n        defaults: true,\n        oneofs: true\n      }\n    );\n    return grpc.loadPackageDefinition(packageDefinition);\n  }\n\n  loadAllProtos(protoRoot) {\n    const hipsterShopPackage = this.packages.hipsterShop.hipstershop;\n    const healthPackage = this.packages.health.grpc.health.v1;\n\n    this.server.addService(\n      hipsterShopPackage.PaymentService.service,\n      {\n        charge: HipsterShopServer.ChargeServiceHandler.bind(this)\n      }\n    );\n\n    this.server.addService(\n      healthPackage.Health.service,\n      {\n        check: HipsterShopServer.CheckHandler.bind(this)\n      }\n    );\n  }\n}\n\nHipsterShopServer.PORT = process.env.PORT;\n\nmodule.exports = HipsterShopServer;\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/.dockerignore",
    "content": "vendor/\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM golang:1.18.4-alpine AS builder\nRUN apk add --no-cache ca-certificates git\nRUN apk add build-base\n\nWORKDIR /src\n# restore dependencies\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\n\n# Skaffold passes in debug-oriented compiler flags\nARG SKAFFOLD_GO_GCFLAGS\nRUN go build -gcflags=\"${SKAFFOLD_GO_GCFLAGS}\" -o /productcatalogservice .\n\nFROM alpine AS release\nRUN apk add --no-cache ca-certificates\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\nWORKDIR /src\nCOPY --from=builder /productcatalogservice ./server\nCOPY products.json .\n\n# Definition of this variable is used by 'skaffold debug' to identify a golang binary.\n# Default behavior - a failure prints a stack trace for the current goroutine.\n# See https://golang.org/pkg/runtime/\nENV GOTRACEBACK=single\n\nEXPOSE 3550\nENTRYPOINT [\"/src/server\"]\n\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/README.md",
    "content": "# productcatalogservice\n\nRun the following command to restore dependencies to `vendor/` directory:\n\n    dep ensure --vendor-only\n\n## Dynamic catalog reloading / artificial delay\n\nThis service has a \"dynamic catalog reloading\" feature that is purposefully\nnot well implemented. The goal of this feature is to allow you to modify the\n`products.json` file and have the changes be picked up without having to\nrestart the service.\n\nHowever, this feature is bugged: the catalog is actually reloaded on each\nrequest, introducing a noticeable delay in the frontend. This delay will also\nshow up in profiling tools: the `parseCatalog` function will take more than 80%\nof the CPU time.\n\nYou can trigger this feature (and the delay) by sending a `USR1` signal and\nremove it (if needed) by sending a `USR2` signal:\n\n```\n# Trigger bug\nkubectl exec \\\n    $(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \\\n    -c server -- kill -USR1 1\n# Remove bug\nkubectl exec \\\n    $(kubectl get pods -l app=productcatalogservice -o jsonpath='{.items[0].metadata.name}') \\\n    -c server -- kill -USR2 1\n```\n\n## Latency injection\n\nThis service has an `EXTRA_LATENCY` environment variable. This will inject a sleep for the specified [time.Duration](https://golang.org/pkg/time/#ParseDuration) on every call to\nto the server.\n\nFor example, use `EXTRA_LATENCY=\"5.5s\"` to sleep for 5.5 seconds on every request.\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/genproto/demo.pb.go",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: demo.proto\n\npackage hipstershop\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.com/golang/protobuf/proto\"\n\tmath \"math\"\n)\n\nimport (\n\tcontext \"golang.org/x/net/context\"\n\tgrpc \"google.golang.org/grpc\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype CartItem struct {\n\tProductId            string   `protobuf:\"bytes,1,opt,name=product_id,json=productId,proto3\" json:\"product_id,omitempty\"`\n\tQuantity             int32    `protobuf:\"varint,2,opt,name=quantity,proto3\" json:\"quantity,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CartItem) Reset()         { *m = CartItem{} }\nfunc (m *CartItem) String() string { return proto.CompactTextString(m) }\nfunc (*CartItem) ProtoMessage()    {}\nfunc (*CartItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{0}\n}\n\nfunc (m *CartItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CartItem.Unmarshal(m, b)\n}\nfunc (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CartItem.Marshal(b, m, deterministic)\n}\nfunc (m *CartItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CartItem.Merge(m, src)\n}\nfunc (m *CartItem) XXX_Size() int {\n\treturn xxx_messageInfo_CartItem.Size(m)\n}\nfunc (m *CartItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_CartItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CartItem proto.InternalMessageInfo\n\nfunc (m *CartItem) GetProductId() string {\n\tif m != nil {\n\t\treturn m.ProductId\n\t}\n\treturn \"\"\n}\n\nfunc (m *CartItem) GetQuantity() int32 {\n\tif m != nil {\n\t\treturn m.Quantity\n\t}\n\treturn 0\n}\n\ntype AddItemRequest struct {\n\tUserId               string    `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItem                 *CartItem `protobuf:\"bytes,2,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *AddItemRequest) Reset()         { *m = AddItemRequest{} }\nfunc (m *AddItemRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AddItemRequest) ProtoMessage()    {}\nfunc (*AddItemRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{1}\n}\n\nfunc (m *AddItemRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AddItemRequest.Unmarshal(m, b)\n}\nfunc (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AddItemRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AddItemRequest.Merge(m, src)\n}\nfunc (m *AddItemRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AddItemRequest.Size(m)\n}\nfunc (m *AddItemRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AddItemRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AddItemRequest proto.InternalMessageInfo\n\nfunc (m *AddItemRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *AddItemRequest) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\ntype EmptyCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *EmptyCartRequest) Reset()         { *m = EmptyCartRequest{} }\nfunc (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*EmptyCartRequest) ProtoMessage()    {}\nfunc (*EmptyCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{2}\n}\n\nfunc (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)\n}\nfunc (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *EmptyCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_EmptyCartRequest.Merge(m, src)\n}\nfunc (m *EmptyCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_EmptyCartRequest.Size(m)\n}\nfunc (m *EmptyCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_EmptyCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo\n\nfunc (m *EmptyCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype GetCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetCartRequest) Reset()         { *m = GetCartRequest{} }\nfunc (m *GetCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetCartRequest) ProtoMessage()    {}\nfunc (*GetCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{3}\n}\n\nfunc (m *GetCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetCartRequest.Unmarshal(m, b)\n}\nfunc (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetCartRequest.Merge(m, src)\n}\nfunc (m *GetCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetCartRequest.Size(m)\n}\nfunc (m *GetCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetCartRequest proto.InternalMessageInfo\n\nfunc (m *GetCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype Cart struct {\n\tUserId               string      `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *Cart) Reset()         { *m = Cart{} }\nfunc (m *Cart) String() string { return proto.CompactTextString(m) }\nfunc (*Cart) ProtoMessage()    {}\nfunc (*Cart) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{4}\n}\n\nfunc (m *Cart) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Cart.Unmarshal(m, b)\n}\nfunc (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Cart.Marshal(b, m, deterministic)\n}\nfunc (m *Cart) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Cart.Merge(m, src)\n}\nfunc (m *Cart) XXX_Size() int {\n\treturn xxx_messageInfo_Cart.Size(m)\n}\nfunc (m *Cart) XXX_DiscardUnknown() {\n\txxx_messageInfo_Cart.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Cart proto.InternalMessageInfo\n\nfunc (m *Cart) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *Cart) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype Empty struct {\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Empty) Reset()         { *m = Empty{} }\nfunc (m *Empty) String() string { return proto.CompactTextString(m) }\nfunc (*Empty) ProtoMessage()    {}\nfunc (*Empty) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{5}\n}\n\nfunc (m *Empty) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Empty.Unmarshal(m, b)\n}\nfunc (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Empty.Marshal(b, m, deterministic)\n}\nfunc (m *Empty) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Empty.Merge(m, src)\n}\nfunc (m *Empty) XXX_Size() int {\n\treturn xxx_messageInfo_Empty.Size(m)\n}\nfunc (m *Empty) XXX_DiscardUnknown() {\n\txxx_messageInfo_Empty.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Empty proto.InternalMessageInfo\n\ntype ListRecommendationsRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tProductIds           []string `protobuf:\"bytes,2,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsRequest) Reset()         { *m = ListRecommendationsRequest{} }\nfunc (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsRequest) ProtoMessage()    {}\nfunc (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{6}\n}\n\nfunc (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsRequest.Merge(m, src)\n}\nfunc (m *ListRecommendationsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Size(m)\n}\nfunc (m *ListRecommendationsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *ListRecommendationsRequest) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype ListRecommendationsResponse struct {\n\tProductIds           []string `protobuf:\"bytes,1,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsResponse) Reset()         { *m = ListRecommendationsResponse{} }\nfunc (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsResponse) ProtoMessage()    {}\nfunc (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{7}\n}\n\nfunc (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsResponse.Merge(m, src)\n}\nfunc (m *ListRecommendationsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Size(m)\n}\nfunc (m *ListRecommendationsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsResponse) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype Product struct {\n\tId          string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName        string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tPicture     string `protobuf:\"bytes,4,opt,name=picture,proto3\" json:\"picture,omitempty\"`\n\tPriceUsd    *Money `protobuf:\"bytes,5,opt,name=price_usd,json=priceUsd,proto3\" json:\"price_usd,omitempty\"`\n\t// Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n\t// other related products.\n\tCategories           []string `protobuf:\"bytes,6,rep,name=categories,proto3\" json:\"categories,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Product) Reset()         { *m = Product{} }\nfunc (m *Product) String() string { return proto.CompactTextString(m) }\nfunc (*Product) ProtoMessage()    {}\nfunc (*Product) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{8}\n}\n\nfunc (m *Product) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Product.Unmarshal(m, b)\n}\nfunc (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Product.Marshal(b, m, deterministic)\n}\nfunc (m *Product) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Product.Merge(m, src)\n}\nfunc (m *Product) XXX_Size() int {\n\treturn xxx_messageInfo_Product.Size(m)\n}\nfunc (m *Product) XXX_DiscardUnknown() {\n\txxx_messageInfo_Product.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Product proto.InternalMessageInfo\n\nfunc (m *Product) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetDescription() string {\n\tif m != nil {\n\t\treturn m.Description\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPicture() string {\n\tif m != nil {\n\t\treturn m.Picture\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPriceUsd() *Money {\n\tif m != nil {\n\t\treturn m.PriceUsd\n\t}\n\treturn nil\n}\n\nfunc (m *Product) GetCategories() []string {\n\tif m != nil {\n\t\treturn m.Categories\n\t}\n\treturn nil\n}\n\ntype ListProductsResponse struct {\n\tProducts             []*Product `protobuf:\"bytes,1,rep,name=products,proto3\" json:\"products,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *ListProductsResponse) Reset()         { *m = ListProductsResponse{} }\nfunc (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListProductsResponse) ProtoMessage()    {}\nfunc (*ListProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{9}\n}\n\nfunc (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)\n}\nfunc (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListProductsResponse.Merge(m, src)\n}\nfunc (m *ListProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListProductsResponse.Size(m)\n}\nfunc (m *ListProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo\n\nfunc (m *ListProductsResponse) GetProducts() []*Product {\n\tif m != nil {\n\t\treturn m.Products\n\t}\n\treturn nil\n}\n\ntype GetProductRequest struct {\n\tId                   string   `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetProductRequest) Reset()         { *m = GetProductRequest{} }\nfunc (m *GetProductRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetProductRequest) ProtoMessage()    {}\nfunc (*GetProductRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{10}\n}\n\nfunc (m *GetProductRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetProductRequest.Unmarshal(m, b)\n}\nfunc (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetProductRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetProductRequest.Merge(m, src)\n}\nfunc (m *GetProductRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetProductRequest.Size(m)\n}\nfunc (m *GetProductRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetProductRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetProductRequest proto.InternalMessageInfo\n\nfunc (m *GetProductRequest) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsRequest struct {\n\tQuery                string   `protobuf:\"bytes,1,opt,name=query,proto3\" json:\"query,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *SearchProductsRequest) Reset()         { *m = SearchProductsRequest{} }\nfunc (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsRequest) ProtoMessage()    {}\nfunc (*SearchProductsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{11}\n}\n\nfunc (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)\n}\nfunc (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsRequest.Merge(m, src)\n}\nfunc (m *SearchProductsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsRequest.Size(m)\n}\nfunc (m *SearchProductsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo\n\nfunc (m *SearchProductsRequest) GetQuery() string {\n\tif m != nil {\n\t\treturn m.Query\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsResponse struct {\n\tResults              []*Product `protobuf:\"bytes,1,rep,name=results,proto3\" json:\"results,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *SearchProductsResponse) Reset()         { *m = SearchProductsResponse{} }\nfunc (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsResponse) ProtoMessage()    {}\nfunc (*SearchProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{12}\n}\n\nfunc (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)\n}\nfunc (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsResponse.Merge(m, src)\n}\nfunc (m *SearchProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsResponse.Size(m)\n}\nfunc (m *SearchProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo\n\nfunc (m *SearchProductsResponse) GetResults() []*Product {\n\tif m != nil {\n\t\treturn m.Results\n\t}\n\treturn nil\n}\n\ntype GetQuoteRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *GetQuoteRequest) Reset()         { *m = GetQuoteRequest{} }\nfunc (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteRequest) ProtoMessage()    {}\nfunc (*GetQuoteRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{13}\n}\n\nfunc (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)\n}\nfunc (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteRequest.Merge(m, src)\n}\nfunc (m *GetQuoteRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteRequest.Size(m)\n}\nfunc (m *GetQuoteRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo\n\nfunc (m *GetQuoteRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *GetQuoteRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype GetQuoteResponse struct {\n\tCostUsd              *Money   `protobuf:\"bytes,1,opt,name=cost_usd,json=costUsd,proto3\" json:\"cost_usd,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetQuoteResponse) Reset()         { *m = GetQuoteResponse{} }\nfunc (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteResponse) ProtoMessage()    {}\nfunc (*GetQuoteResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{14}\n}\n\nfunc (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)\n}\nfunc (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteResponse.Merge(m, src)\n}\nfunc (m *GetQuoteResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteResponse.Size(m)\n}\nfunc (m *GetQuoteResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo\n\nfunc (m *GetQuoteResponse) GetCostUsd() *Money {\n\tif m != nil {\n\t\treturn m.CostUsd\n\t}\n\treturn nil\n}\n\ntype ShipOrderRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *ShipOrderRequest) Reset()         { *m = ShipOrderRequest{} }\nfunc (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderRequest) ProtoMessage()    {}\nfunc (*ShipOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{15}\n}\n\nfunc (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)\n}\nfunc (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderRequest.Merge(m, src)\n}\nfunc (m *ShipOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderRequest.Size(m)\n}\nfunc (m *ShipOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo\n\nfunc (m *ShipOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *ShipOrderRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype ShipOrderResponse struct {\n\tTrackingId           string   `protobuf:\"bytes,1,opt,name=tracking_id,json=trackingId,proto3\" json:\"tracking_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ShipOrderResponse) Reset()         { *m = ShipOrderResponse{} }\nfunc (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderResponse) ProtoMessage()    {}\nfunc (*ShipOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{16}\n}\n\nfunc (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)\n}\nfunc (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderResponse.Merge(m, src)\n}\nfunc (m *ShipOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderResponse.Size(m)\n}\nfunc (m *ShipOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo\n\nfunc (m *ShipOrderResponse) GetTrackingId() string {\n\tif m != nil {\n\t\treturn m.TrackingId\n\t}\n\treturn \"\"\n}\n\ntype Address struct {\n\tStreetAddress        string   `protobuf:\"bytes,1,opt,name=street_address,json=streetAddress,proto3\" json:\"street_address,omitempty\"`\n\tCity                 string   `protobuf:\"bytes,2,opt,name=city,proto3\" json:\"city,omitempty\"`\n\tState                string   `protobuf:\"bytes,3,opt,name=state,proto3\" json:\"state,omitempty\"`\n\tCountry              string   `protobuf:\"bytes,4,opt,name=country,proto3\" json:\"country,omitempty\"`\n\tZipCode              int32    `protobuf:\"varint,5,opt,name=zip_code,json=zipCode,proto3\" json:\"zip_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Address) Reset()         { *m = Address{} }\nfunc (m *Address) String() string { return proto.CompactTextString(m) }\nfunc (*Address) ProtoMessage()    {}\nfunc (*Address) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{17}\n}\n\nfunc (m *Address) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Address.Unmarshal(m, b)\n}\nfunc (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Address.Marshal(b, m, deterministic)\n}\nfunc (m *Address) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Address.Merge(m, src)\n}\nfunc (m *Address) XXX_Size() int {\n\treturn xxx_messageInfo_Address.Size(m)\n}\nfunc (m *Address) XXX_DiscardUnknown() {\n\txxx_messageInfo_Address.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Address proto.InternalMessageInfo\n\nfunc (m *Address) GetStreetAddress() string {\n\tif m != nil {\n\t\treturn m.StreetAddress\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCity() string {\n\tif m != nil {\n\t\treturn m.City\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetState() string {\n\tif m != nil {\n\t\treturn m.State\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCountry() string {\n\tif m != nil {\n\t\treturn m.Country\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetZipCode() int32 {\n\tif m != nil {\n\t\treturn m.ZipCode\n\t}\n\treturn 0\n}\n\n// Represents an amount of money with its currency type.\ntype Money struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCode string `protobuf:\"bytes,1,opt,name=currency_code,json=currencyCode,proto3\" json:\"currency_code,omitempty\"`\n\t// The whole units of the amount.\n\t// For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n\tUnits int64 `protobuf:\"varint,2,opt,name=units,proto3\" json:\"units,omitempty\"`\n\t// Number of nano (10^-9) units of the amount.\n\t// The value must be between -999,999,999 and +999,999,999 inclusive.\n\t// If `units` is positive, `nanos` must be positive or zero.\n\t// If `units` is zero, `nanos` can be positive, zero, or negative.\n\t// If `units` is negative, `nanos` must be negative or zero.\n\t// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n\tNanos                int32    `protobuf:\"varint,3,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Money) Reset()         { *m = Money{} }\nfunc (m *Money) String() string { return proto.CompactTextString(m) }\nfunc (*Money) ProtoMessage()    {}\nfunc (*Money) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{18}\n}\n\nfunc (m *Money) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Money.Unmarshal(m, b)\n}\nfunc (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Money.Marshal(b, m, deterministic)\n}\nfunc (m *Money) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Money.Merge(m, src)\n}\nfunc (m *Money) XXX_Size() int {\n\treturn xxx_messageInfo_Money.Size(m)\n}\nfunc (m *Money) XXX_DiscardUnknown() {\n\txxx_messageInfo_Money.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Money proto.InternalMessageInfo\n\nfunc (m *Money) GetCurrencyCode() string {\n\tif m != nil {\n\t\treturn m.CurrencyCode\n\t}\n\treturn \"\"\n}\n\nfunc (m *Money) GetUnits() int64 {\n\tif m != nil {\n\t\treturn m.Units\n\t}\n\treturn 0\n}\n\nfunc (m *Money) GetNanos() int32 {\n\tif m != nil {\n\t\treturn m.Nanos\n\t}\n\treturn 0\n}\n\ntype GetSupportedCurrenciesResponse struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCodes        []string `protobuf:\"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3\" json:\"currency_codes,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetSupportedCurrenciesResponse) Reset()         { *m = GetSupportedCurrenciesResponse{} }\nfunc (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetSupportedCurrenciesResponse) ProtoMessage()    {}\nfunc (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{19}\n}\n\nfunc (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo\n\nfunc (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string {\n\tif m != nil {\n\t\treturn m.CurrencyCodes\n\t}\n\treturn nil\n}\n\ntype CurrencyConversionRequest struct {\n\tFrom *Money `protobuf:\"bytes,1,opt,name=from,proto3\" json:\"from,omitempty\"`\n\t// The 3-letter currency code defined in ISO 4217.\n\tToCode               string   `protobuf:\"bytes,2,opt,name=to_code,json=toCode,proto3\" json:\"to_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CurrencyConversionRequest) Reset()         { *m = CurrencyConversionRequest{} }\nfunc (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }\nfunc (*CurrencyConversionRequest) ProtoMessage()    {}\nfunc (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{20}\n}\n\nfunc (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)\n}\nfunc (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)\n}\nfunc (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CurrencyConversionRequest.Merge(m, src)\n}\nfunc (m *CurrencyConversionRequest) XXX_Size() int {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Size(m)\n}\nfunc (m *CurrencyConversionRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo\n\nfunc (m *CurrencyConversionRequest) GetFrom() *Money {\n\tif m != nil {\n\t\treturn m.From\n\t}\n\treturn nil\n}\n\nfunc (m *CurrencyConversionRequest) GetToCode() string {\n\tif m != nil {\n\t\treturn m.ToCode\n\t}\n\treturn \"\"\n}\n\ntype CreditCardInfo struct {\n\tCreditCardNumber          string   `protobuf:\"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3\" json:\"credit_card_number,omitempty\"`\n\tCreditCardCvv             int32    `protobuf:\"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3\" json:\"credit_card_cvv,omitempty\"`\n\tCreditCardExpirationYear  int32    `protobuf:\"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3\" json:\"credit_card_expiration_year,omitempty\"`\n\tCreditCardExpirationMonth int32    `protobuf:\"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3\" json:\"credit_card_expiration_month,omitempty\"`\n\tXXX_NoUnkeyedLiteral      struct{} `json:\"-\"`\n\tXXX_unrecognized          []byte   `json:\"-\"`\n\tXXX_sizecache             int32    `json:\"-\"`\n}\n\nfunc (m *CreditCardInfo) Reset()         { *m = CreditCardInfo{} }\nfunc (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }\nfunc (*CreditCardInfo) ProtoMessage()    {}\nfunc (*CreditCardInfo) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{21}\n}\n\nfunc (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)\n}\nfunc (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)\n}\nfunc (m *CreditCardInfo) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CreditCardInfo.Merge(m, src)\n}\nfunc (m *CreditCardInfo) XXX_Size() int {\n\treturn xxx_messageInfo_CreditCardInfo.Size(m)\n}\nfunc (m *CreditCardInfo) XXX_DiscardUnknown() {\n\txxx_messageInfo_CreditCardInfo.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo\n\nfunc (m *CreditCardInfo) GetCreditCardNumber() string {\n\tif m != nil {\n\t\treturn m.CreditCardNumber\n\t}\n\treturn \"\"\n}\n\nfunc (m *CreditCardInfo) GetCreditCardCvv() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardCvv\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationYear() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationYear\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationMonth\n\t}\n\treturn 0\n}\n\ntype ChargeRequest struct {\n\tAmount               *Money          `protobuf:\"bytes,1,opt,name=amount,proto3\" json:\"amount,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,2,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *ChargeRequest) Reset()         { *m = ChargeRequest{} }\nfunc (m *ChargeRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeRequest) ProtoMessage()    {}\nfunc (*ChargeRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{22}\n}\n\nfunc (m *ChargeRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeRequest.Unmarshal(m, b)\n}\nfunc (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeRequest.Merge(m, src)\n}\nfunc (m *ChargeRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeRequest.Size(m)\n}\nfunc (m *ChargeRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeRequest proto.InternalMessageInfo\n\nfunc (m *ChargeRequest) GetAmount() *Money {\n\tif m != nil {\n\t\treturn m.Amount\n\t}\n\treturn nil\n}\n\nfunc (m *ChargeRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype ChargeResponse struct {\n\tTransactionId        string   `protobuf:\"bytes,1,opt,name=transaction_id,json=transactionId,proto3\" json:\"transaction_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ChargeResponse) Reset()         { *m = ChargeResponse{} }\nfunc (m *ChargeResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeResponse) ProtoMessage()    {}\nfunc (*ChargeResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{23}\n}\n\nfunc (m *ChargeResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeResponse.Unmarshal(m, b)\n}\nfunc (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeResponse.Merge(m, src)\n}\nfunc (m *ChargeResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeResponse.Size(m)\n}\nfunc (m *ChargeResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeResponse proto.InternalMessageInfo\n\nfunc (m *ChargeResponse) GetTransactionId() string {\n\tif m != nil {\n\t\treturn m.TransactionId\n\t}\n\treturn \"\"\n}\n\ntype OrderItem struct {\n\tItem                 *CartItem `protobuf:\"bytes,1,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tCost                 *Money    `protobuf:\"bytes,2,opt,name=cost,proto3\" json:\"cost,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *OrderItem) Reset()         { *m = OrderItem{} }\nfunc (m *OrderItem) String() string { return proto.CompactTextString(m) }\nfunc (*OrderItem) ProtoMessage()    {}\nfunc (*OrderItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{24}\n}\n\nfunc (m *OrderItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderItem.Unmarshal(m, b)\n}\nfunc (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)\n}\nfunc (m *OrderItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderItem.Merge(m, src)\n}\nfunc (m *OrderItem) XXX_Size() int {\n\treturn xxx_messageInfo_OrderItem.Size(m)\n}\nfunc (m *OrderItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderItem proto.InternalMessageInfo\n\nfunc (m *OrderItem) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\nfunc (m *OrderItem) GetCost() *Money {\n\tif m != nil {\n\t\treturn m.Cost\n\t}\n\treturn nil\n}\n\ntype OrderResult struct {\n\tOrderId              string       `protobuf:\"bytes,1,opt,name=order_id,json=orderId,proto3\" json:\"order_id,omitempty\"`\n\tShippingTrackingId   string       `protobuf:\"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3\" json:\"shipping_tracking_id,omitempty\"`\n\tShippingCost         *Money       `protobuf:\"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3\" json:\"shipping_cost,omitempty\"`\n\tShippingAddress      *Address     `protobuf:\"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3\" json:\"shipping_address,omitempty\"`\n\tItems                []*OrderItem `protobuf:\"bytes,5,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *OrderResult) Reset()         { *m = OrderResult{} }\nfunc (m *OrderResult) String() string { return proto.CompactTextString(m) }\nfunc (*OrderResult) ProtoMessage()    {}\nfunc (*OrderResult) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{25}\n}\n\nfunc (m *OrderResult) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderResult.Unmarshal(m, b)\n}\nfunc (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)\n}\nfunc (m *OrderResult) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderResult.Merge(m, src)\n}\nfunc (m *OrderResult) XXX_Size() int {\n\treturn xxx_messageInfo_OrderResult.Size(m)\n}\nfunc (m *OrderResult) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderResult.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderResult proto.InternalMessageInfo\n\nfunc (m *OrderResult) GetOrderId() string {\n\tif m != nil {\n\t\treturn m.OrderId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingTrackingId() string {\n\tif m != nil {\n\t\treturn m.ShippingTrackingId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingCost() *Money {\n\tif m != nil {\n\t\treturn m.ShippingCost\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetShippingAddress() *Address {\n\tif m != nil {\n\t\treturn m.ShippingAddress\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetItems() []*OrderItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype SendOrderConfirmationRequest struct {\n\tEmail                string       `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tOrder                *OrderResult `protobuf:\"bytes,2,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *SendOrderConfirmationRequest) Reset()         { *m = SendOrderConfirmationRequest{} }\nfunc (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SendOrderConfirmationRequest) ProtoMessage()    {}\nfunc (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{26}\n}\n\nfunc (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Size(m)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo\n\nfunc (m *SendOrderConfirmationRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *SendOrderConfirmationRequest) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype PlaceOrderRequest struct {\n\tUserId               string          `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tUserCurrency         string          `protobuf:\"bytes,2,opt,name=user_currency,json=userCurrency,proto3\" json:\"user_currency,omitempty\"`\n\tAddress              *Address        `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tEmail                string          `protobuf:\"bytes,5,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,6,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *PlaceOrderRequest) Reset()         { *m = PlaceOrderRequest{} }\nfunc (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderRequest) ProtoMessage()    {}\nfunc (*PlaceOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{27}\n}\n\nfunc (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderRequest.Merge(m, src)\n}\nfunc (m *PlaceOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderRequest.Size(m)\n}\nfunc (m *PlaceOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo\n\nfunc (m *PlaceOrderRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetUserCurrency() string {\n\tif m != nil {\n\t\treturn m.UserCurrency\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *PlaceOrderRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype PlaceOrderResponse struct {\n\tOrder                *OrderResult `protobuf:\"bytes,1,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *PlaceOrderResponse) Reset()         { *m = PlaceOrderResponse{} }\nfunc (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderResponse) ProtoMessage()    {}\nfunc (*PlaceOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{28}\n}\n\nfunc (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderResponse.Merge(m, src)\n}\nfunc (m *PlaceOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderResponse.Size(m)\n}\nfunc (m *PlaceOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo\n\nfunc (m *PlaceOrderResponse) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype AdRequest struct {\n\t// List of important key words from the current page describing the context.\n\tContextKeys          []string `protobuf:\"bytes,1,rep,name=context_keys,json=contextKeys,proto3\" json:\"context_keys,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdRequest) Reset()         { *m = AdRequest{} }\nfunc (m *AdRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AdRequest) ProtoMessage()    {}\nfunc (*AdRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{29}\n}\n\nfunc (m *AdRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdRequest.Unmarshal(m, b)\n}\nfunc (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AdRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdRequest.Merge(m, src)\n}\nfunc (m *AdRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AdRequest.Size(m)\n}\nfunc (m *AdRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdRequest proto.InternalMessageInfo\n\nfunc (m *AdRequest) GetContextKeys() []string {\n\tif m != nil {\n\t\treturn m.ContextKeys\n\t}\n\treturn nil\n}\n\ntype AdResponse struct {\n\tAds                  []*Ad    `protobuf:\"bytes,1,rep,name=ads,proto3\" json:\"ads,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdResponse) Reset()         { *m = AdResponse{} }\nfunc (m *AdResponse) String() string { return proto.CompactTextString(m) }\nfunc (*AdResponse) ProtoMessage()    {}\nfunc (*AdResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{30}\n}\n\nfunc (m *AdResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdResponse.Unmarshal(m, b)\n}\nfunc (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)\n}\nfunc (m *AdResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdResponse.Merge(m, src)\n}\nfunc (m *AdResponse) XXX_Size() int {\n\treturn xxx_messageInfo_AdResponse.Size(m)\n}\nfunc (m *AdResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdResponse proto.InternalMessageInfo\n\nfunc (m *AdResponse) GetAds() []*Ad {\n\tif m != nil {\n\t\treturn m.Ads\n\t}\n\treturn nil\n}\n\ntype Ad struct {\n\t// url to redirect to when an ad is clicked.\n\tRedirectUrl string `protobuf:\"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3\" json:\"redirect_url,omitempty\"`\n\t// short advertisement text to display.\n\tText                 string   `protobuf:\"bytes,2,opt,name=text,proto3\" json:\"text,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Ad) Reset()         { *m = Ad{} }\nfunc (m *Ad) String() string { return proto.CompactTextString(m) }\nfunc (*Ad) ProtoMessage()    {}\nfunc (*Ad) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{31}\n}\n\nfunc (m *Ad) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Ad.Unmarshal(m, b)\n}\nfunc (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Ad.Marshal(b, m, deterministic)\n}\nfunc (m *Ad) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Ad.Merge(m, src)\n}\nfunc (m *Ad) XXX_Size() int {\n\treturn xxx_messageInfo_Ad.Size(m)\n}\nfunc (m *Ad) XXX_DiscardUnknown() {\n\txxx_messageInfo_Ad.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Ad proto.InternalMessageInfo\n\nfunc (m *Ad) GetRedirectUrl() string {\n\tif m != nil {\n\t\treturn m.RedirectUrl\n\t}\n\treturn \"\"\n}\n\nfunc (m *Ad) GetText() string {\n\tif m != nil {\n\t\treturn m.Text\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*CartItem)(nil), \"hipstershop.CartItem\")\n\tproto.RegisterType((*AddItemRequest)(nil), \"hipstershop.AddItemRequest\")\n\tproto.RegisterType((*EmptyCartRequest)(nil), \"hipstershop.EmptyCartRequest\")\n\tproto.RegisterType((*GetCartRequest)(nil), \"hipstershop.GetCartRequest\")\n\tproto.RegisterType((*Cart)(nil), \"hipstershop.Cart\")\n\tproto.RegisterType((*Empty)(nil), \"hipstershop.Empty\")\n\tproto.RegisterType((*ListRecommendationsRequest)(nil), \"hipstershop.ListRecommendationsRequest\")\n\tproto.RegisterType((*ListRecommendationsResponse)(nil), \"hipstershop.ListRecommendationsResponse\")\n\tproto.RegisterType((*Product)(nil), \"hipstershop.Product\")\n\tproto.RegisterType((*ListProductsResponse)(nil), \"hipstershop.ListProductsResponse\")\n\tproto.RegisterType((*GetProductRequest)(nil), \"hipstershop.GetProductRequest\")\n\tproto.RegisterType((*SearchProductsRequest)(nil), \"hipstershop.SearchProductsRequest\")\n\tproto.RegisterType((*SearchProductsResponse)(nil), \"hipstershop.SearchProductsResponse\")\n\tproto.RegisterType((*GetQuoteRequest)(nil), \"hipstershop.GetQuoteRequest\")\n\tproto.RegisterType((*GetQuoteResponse)(nil), \"hipstershop.GetQuoteResponse\")\n\tproto.RegisterType((*ShipOrderRequest)(nil), \"hipstershop.ShipOrderRequest\")\n\tproto.RegisterType((*ShipOrderResponse)(nil), \"hipstershop.ShipOrderResponse\")\n\tproto.RegisterType((*Address)(nil), \"hipstershop.Address\")\n\tproto.RegisterType((*Money)(nil), \"hipstershop.Money\")\n\tproto.RegisterType((*GetSupportedCurrenciesResponse)(nil), \"hipstershop.GetSupportedCurrenciesResponse\")\n\tproto.RegisterType((*CurrencyConversionRequest)(nil), \"hipstershop.CurrencyConversionRequest\")\n\tproto.RegisterType((*CreditCardInfo)(nil), \"hipstershop.CreditCardInfo\")\n\tproto.RegisterType((*ChargeRequest)(nil), \"hipstershop.ChargeRequest\")\n\tproto.RegisterType((*ChargeResponse)(nil), \"hipstershop.ChargeResponse\")\n\tproto.RegisterType((*OrderItem)(nil), \"hipstershop.OrderItem\")\n\tproto.RegisterType((*OrderResult)(nil), \"hipstershop.OrderResult\")\n\tproto.RegisterType((*SendOrderConfirmationRequest)(nil), \"hipstershop.SendOrderConfirmationRequest\")\n\tproto.RegisterType((*PlaceOrderRequest)(nil), \"hipstershop.PlaceOrderRequest\")\n\tproto.RegisterType((*PlaceOrderResponse)(nil), \"hipstershop.PlaceOrderResponse\")\n\tproto.RegisterType((*AdRequest)(nil), \"hipstershop.AdRequest\")\n\tproto.RegisterType((*AdResponse)(nil), \"hipstershop.AdResponse\")\n\tproto.RegisterType((*Ad)(nil), \"hipstershop.Ad\")\n}\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ context.Context\nvar _ grpc.ClientConn\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\nconst _ = grpc.SupportPackageIsVersion4\n\n// CartServiceClient is the client API for CartService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CartServiceClient interface {\n\tAddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error)\n\tGetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error)\n\tEmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype cartServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient {\n\treturn &cartServiceClient{cc}\n}\n\nfunc (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/AddItem\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) {\n\tout := new(Cart)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/GetCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/EmptyCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CartServiceServer is the server API for CartService service.\ntype CartServiceServer interface {\n\tAddItem(context.Context, *AddItemRequest) (*Empty, error)\n\tGetCart(context.Context, *GetCartRequest) (*Cart, error)\n\tEmptyCart(context.Context, *EmptyCartRequest) (*Empty, error)\n}\n\nfunc RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) {\n\ts.RegisterService(&_CartService_serviceDesc, srv)\n}\n\nfunc _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddItemRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/AddItem\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/GetCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(EmptyCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/EmptyCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CartService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CartService\",\n\tHandlerType: (*CartServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"AddItem\",\n\t\t\tHandler:    _CartService_AddItem_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetCart\",\n\t\t\tHandler:    _CartService_GetCart_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"EmptyCart\",\n\t\t\tHandler:    _CartService_EmptyCart_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// RecommendationServiceClient is the client API for RecommendationService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype RecommendationServiceClient interface {\n\tListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error)\n}\n\ntype recommendationServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {\n\treturn &recommendationServiceClient{cc}\n}\n\nfunc (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) {\n\tout := new(ListRecommendationsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.RecommendationService/ListRecommendations\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// RecommendationServiceServer is the server API for RecommendationService service.\ntype RecommendationServiceServer interface {\n\tListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error)\n}\n\nfunc RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {\n\ts.RegisterService(&_RecommendationService_serviceDesc, srv)\n}\n\nfunc _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListRecommendationsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.RecommendationService/ListRecommendations\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _RecommendationService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.RecommendationService\",\n\tHandlerType: (*RecommendationServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListRecommendations\",\n\t\t\tHandler:    _RecommendationService_ListRecommendations_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ProductCatalogServiceClient is the client API for ProductCatalogService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ProductCatalogServiceClient interface {\n\tListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error)\n\tGetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error)\n\tSearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error)\n}\n\ntype productCatalogServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient {\n\treturn &productCatalogServiceClient{cc}\n}\n\nfunc (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) {\n\tout := new(ListProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/ListProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) {\n\tout := new(Product)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/GetProduct\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) {\n\tout := new(SearchProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/SearchProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ProductCatalogServiceServer is the server API for ProductCatalogService service.\ntype ProductCatalogServiceServer interface {\n\tListProducts(context.Context, *Empty) (*ListProductsResponse, error)\n\tGetProduct(context.Context, *GetProductRequest) (*Product, error)\n\tSearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error)\n}\n\nfunc RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) {\n\ts.RegisterService(&_ProductCatalogService_serviceDesc, srv)\n}\n\nfunc _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/ListProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetProductRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/GetProduct\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SearchProductsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/SearchProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ProductCatalogService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ProductCatalogService\",\n\tHandlerType: (*ProductCatalogServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListProducts\",\n\t\t\tHandler:    _ProductCatalogService_ListProducts_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetProduct\",\n\t\t\tHandler:    _ProductCatalogService_GetProduct_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"SearchProducts\",\n\t\t\tHandler:    _ProductCatalogService_SearchProducts_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ShippingServiceClient is the client API for ShippingService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ShippingServiceClient interface {\n\tGetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error)\n\tShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error)\n}\n\ntype shippingServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient {\n\treturn &shippingServiceClient{cc}\n}\n\nfunc (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) {\n\tout := new(GetQuoteResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/GetQuote\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) {\n\tout := new(ShipOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/ShipOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ShippingServiceServer is the server API for ShippingService service.\ntype ShippingServiceServer interface {\n\tGetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error)\n\tShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error)\n}\n\nfunc RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) {\n\ts.RegisterService(&_ShippingService_serviceDesc, srv)\n}\n\nfunc _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetQuoteRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/GetQuote\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ShipOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/ShipOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ShippingService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ShippingService\",\n\tHandlerType: (*ShippingServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetQuote\",\n\t\t\tHandler:    _ShippingService_GetQuote_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"ShipOrder\",\n\t\t\tHandler:    _ShippingService_ShipOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CurrencyServiceClient is the client API for CurrencyService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CurrencyServiceClient interface {\n\tGetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error)\n\tConvert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error)\n}\n\ntype currencyServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient {\n\treturn &currencyServiceClient{cc}\n}\n\nfunc (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) {\n\tout := new(GetSupportedCurrenciesResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/GetSupportedCurrencies\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) {\n\tout := new(Money)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/Convert\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CurrencyServiceServer is the server API for CurrencyService service.\ntype CurrencyServiceServer interface {\n\tGetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error)\n\tConvert(context.Context, *CurrencyConversionRequest) (*Money, error)\n}\n\nfunc RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) {\n\ts.RegisterService(&_CurrencyService_serviceDesc, srv)\n}\n\nfunc _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/GetSupportedCurrencies\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(CurrencyConversionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/Convert\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CurrencyService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CurrencyService\",\n\tHandlerType: (*CurrencyServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetSupportedCurrencies\",\n\t\t\tHandler:    _CurrencyService_GetSupportedCurrencies_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"Convert\",\n\t\t\tHandler:    _CurrencyService_Convert_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// PaymentServiceClient is the client API for PaymentService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype PaymentServiceClient interface {\n\tCharge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error)\n}\n\ntype paymentServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient {\n\treturn &paymentServiceClient{cc}\n}\n\nfunc (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) {\n\tout := new(ChargeResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.PaymentService/Charge\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// PaymentServiceServer is the server API for PaymentService service.\ntype PaymentServiceServer interface {\n\tCharge(context.Context, *ChargeRequest) (*ChargeResponse, error)\n}\n\nfunc RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) {\n\ts.RegisterService(&_PaymentService_serviceDesc, srv)\n}\n\nfunc _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ChargeRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.PaymentService/Charge\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _PaymentService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.PaymentService\",\n\tHandlerType: (*PaymentServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Charge\",\n\t\t\tHandler:    _PaymentService_Charge_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// EmailServiceClient is the client API for EmailService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype EmailServiceClient interface {\n\tSendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype emailServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient {\n\treturn &emailServiceClient{cc}\n}\n\nfunc (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.EmailService/SendOrderConfirmation\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// EmailServiceServer is the server API for EmailService service.\ntype EmailServiceServer interface {\n\tSendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error)\n}\n\nfunc RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) {\n\ts.RegisterService(&_EmailService_serviceDesc, srv)\n}\n\nfunc _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SendOrderConfirmationRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.EmailService/SendOrderConfirmation\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _EmailService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.EmailService\",\n\tHandlerType: (*EmailServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"SendOrderConfirmation\",\n\t\t\tHandler:    _EmailService_SendOrderConfirmation_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CheckoutServiceClient is the client API for CheckoutService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CheckoutServiceClient interface {\n\tPlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error)\n}\n\ntype checkoutServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient {\n\treturn &checkoutServiceClient{cc}\n}\n\nfunc (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) {\n\tout := new(PlaceOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CheckoutService/PlaceOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CheckoutServiceServer is the server API for CheckoutService service.\ntype CheckoutServiceServer interface {\n\tPlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error)\n}\n\nfunc RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) {\n\ts.RegisterService(&_CheckoutService_serviceDesc, srv)\n}\n\nfunc _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PlaceOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CheckoutService/PlaceOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CheckoutService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CheckoutService\",\n\tHandlerType: (*CheckoutServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"PlaceOrder\",\n\t\t\tHandler:    _CheckoutService_PlaceOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// AdServiceClient is the client API for AdService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype AdServiceClient interface {\n\tGetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error)\n}\n\ntype adServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient {\n\treturn &adServiceClient{cc}\n}\n\nfunc (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) {\n\tout := new(AdResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.AdService/GetAds\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// AdServiceServer is the server API for AdService service.\ntype AdServiceServer interface {\n\tGetAds(context.Context, *AdRequest) (*AdResponse, error)\n}\n\nfunc RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) {\n\ts.RegisterService(&_AdService_serviceDesc, srv)\n}\n\nfunc _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AdRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.AdService/GetAds\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _AdService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.AdService\",\n\tHandlerType: (*AdServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetAds\",\n\t\t\tHandler:    _AdService_GetAds_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\nfunc init() { proto.RegisterFile(\"demo.proto\", fileDescriptor_ca53982754088a9d) }\n\nvar fileDescriptor_ca53982754088a9d = []byte{\n\t// 1500 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7,\n\t0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81,\n\t0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0,\n\t0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc,\n\t0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8,\n\t0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8,\n\t0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29,\n\t0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88,\n\t0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20,\n\t0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93,\n\t0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0,\n\t0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad,\n\t0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e,\n\t0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85,\n\t0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32,\n\t0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20,\n\t0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2,\n\t0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7,\n\t0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d,\n\t0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8,\n\t0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93,\n\t0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b,\n\t0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28,\n\t0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04,\n\t0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72,\n\t0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99,\n\t0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab,\n\t0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7,\n\t0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26,\n\t0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f,\n\t0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0,\n\t0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07,\n\t0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe,\n\t0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34,\n\t0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52,\n\t0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3,\n\t0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11,\n\t0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63,\n\t0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13,\n\t0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49,\n\t0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a,\n\t0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29,\n\t0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca,\n\t0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55,\n\t0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71,\n\t0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97,\n\t0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d,\n\t0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff,\n\t0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb,\n\t0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1,\n\t0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8,\n\t0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4,\n\t0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0,\n\t0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69,\n\t0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb,\n\t0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d,\n\t0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7,\n\t0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99,\n\t0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98,\n\t0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9,\n\t0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02,\n\t0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d,\n\t0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d,\n\t0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa,\n\t0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9,\n\t0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7,\n\t0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce,\n\t0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47,\n\t0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d,\n\t0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23,\n\t0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac,\n\t0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca,\n\t0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb,\n\t0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99,\n\t0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe,\n\t0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff,\n\t0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07,\n\t0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87,\n\t0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8,\n\t0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33,\n\t0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93,\n\t0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2,\n\t0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43,\n\t0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6,\n\t0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31,\n\t0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21,\n\t0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc,\n\t0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43,\n\t0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd,\n\t0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2,\n\t0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f,\n\t0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a,\n\t0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b,\n\t0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00,\n}\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_productcatalogservice_genproto]\n\nPATH=$PATH:$GOPATH/bin\nprotodir=../../pb\n\nprotoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto\n\n# [END gke_productcatalogservice_genproto]"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/go.mod",
    "content": "module github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice\n\ngo 1.18\n\nrequire (\n\tcloud.google.com/go/profiler v0.3.0\n\tcontrib.go.opencensus.io/exporter/jaeger v0.2.1\n\tcontrib.go.opencensus.io/exporter/stackdriver v0.13.12\n\tgithub.com/golang/protobuf v1.5.2\n\tgithub.com/google/go-cmp v0.5.8\n\tgithub.com/sirupsen/logrus v1.8.1\n\tgo.opencensus.io v0.23.0\n\tgolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b\n\tgoogle.golang.org/grpc v1.48.0\n)\n\nrequire (\n\tcloud.google.com/go v0.100.2 // indirect\n\tcloud.google.com/go/compute v1.6.1 // indirect\n\tcloud.google.com/go/monitoring v1.1.0 // indirect\n\tcloud.google.com/go/trace v1.0.0 // indirect\n\tgithub.com/aws/aws-sdk-go v1.43.31 // indirect\n\tgithub.com/census-instrumentation/opencensus-proto v0.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.1.1 // indirect\n\tgithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect\n\tgithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.4.0 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/prometheus/prometheus v2.5.0+incompatible // indirect\n\tgithub.com/uber/jaeger-client-go v2.25.0+incompatible // indirect\n\tgolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect\n\tgolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgoogle.golang.org/api v0.78.0 // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect\n\tgoogle.golang.org/protobuf v1.28.0 // indirect\n)\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo=\ncloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=\ncloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ=\ncloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4=\ncloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo=\ncloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=\ncloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=\ngithub.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=\ngithub.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0=\ngithub.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=\ngithub.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=\ngoogle.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/products.json",
    "content": "{\n    \"products\": [\n        {\n            \"id\": \"OLJCESPC7Z\",\n            \"name\": \"Sunglasses\",\n            \"description\": \"Add a modern touch to your outfits with these sleek aviator sunglasses.\",\n            \"picture\": \"/static/img/products/sunglasses.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 19,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"accessories\"]\n        },\n        {\n            \"id\": \"66VCHSJNUP\",\n            \"name\": \"Tank Top\",\n            \"description\": \"Perfectly cropped cotton tank, with a scooped neckline.\",\n            \"picture\": \"/static/img/products/tank-top.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 18,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"clothing\", \"tops\"]\n        },\n        {\n            \"id\": \"1YMWWN1N4O\",\n            \"name\": \"Watch\",\n            \"description\": \"This gold-tone stainless steel watch will work with most of your outfits.\",\n            \"picture\": \"/static/img/products/watch.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 109,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"accessories\"]\n        },\n        {\n            \"id\": \"L9ECAV7KIM\",\n            \"name\": \"Loafers\",\n            \"description\": \"A neat addition to your summer wardrobe.\",\n            \"picture\": \"/static/img/products/loafers.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 89,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"footwear\"]\n        },\n        {\n            \"id\": \"2ZYFJ3GM2N\",\n            \"name\": \"Hairdryer\",\n            \"description\": \"This lightweight hairdryer has 3 heat and speed settings. It's perfect for travel.\",\n            \"picture\": \"/static/img/products/hairdryer.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 24,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"hair\", \"beauty\"]\n        },\n        {\n            \"id\": \"0PUK6V6EV0\",\n            \"name\": \"Candle Holder\",\n            \"description\": \"This small but intricate candle holder is an excellent gift.\",\n            \"picture\": \"/static/img/products/candle-holder.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 18,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"decor\", \"home\"]\n        },\n        {\n            \"id\": \"LS4PSXUNUM\",\n            \"name\": \"Salt & Pepper Shakers\",\n            \"description\": \"Add some flavor to your kitchen.\",\n            \"picture\": \"/static/img/products/salt-and-pepper-shakers.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 18,\n                \"nanos\": 490000000\n            },\n            \"categories\": [\"kitchen\"]\n        },\n        {\n            \"id\": \"9SIQT8TOJO\",\n            \"name\": \"Bamboo Glass Jar\",\n            \"description\": \"This bamboo glass jar can hold 57 oz (1.7 l) and is perfect for any kitchen.\",\n            \"picture\": \"/static/img/products/bamboo-glass-jar.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 5,\n                \"nanos\": 490000000\n            },\n            \"categories\": [\"kitchen\"]\n        },\n        {\n            \"id\": \"6E92ZMYYFZ\",\n            \"name\": \"Mug\",\n            \"description\": \"A simple mug with a mustard interior.\",\n            \"picture\": \"/static/img/products/mug.jpg\",\n            \"priceUsd\": {\n                \"currencyCode\": \"USD\",\n                \"units\": 8,\n                \"nanos\": 990000000\n            },\n            \"categories\": [\"kitchen\"]\n        }\n    ]\n}\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/server.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice/genproto\"\n\thealthpb \"google.golang.org/grpc/health/grpc_health_v1\"\n\n\t\"cloud.google.com/go/profiler\"\n\t\"contrib.go.opencensus.io/exporter/jaeger\"\n\t\"contrib.go.opencensus.io/exporter/stackdriver\"\n\t\"github.com/golang/protobuf/jsonpb\"\n\t\"github.com/sirupsen/logrus\"\n\t//  \"go.opencensus.io/exporter/jaeger\"\n\t\"go.opencensus.io/plugin/ocgrpc\"\n\t\"go.opencensus.io/stats/view\"\n\t\"go.opencensus.io/trace\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nvar (\n\tcat          pb.ListProductsResponse\n\tcatalogMutex *sync.Mutex\n\tlog          *logrus.Logger\n\textraLatency time.Duration\n\n\tport = \"3550\"\n\n\treloadCatalog bool\n)\n\nfunc init() {\n\tlog = logrus.New()\n\tlog.Formatter = &logrus.JSONFormatter{\n\t\tFieldMap: logrus.FieldMap{\n\t\t\tlogrus.FieldKeyTime:  \"timestamp\",\n\t\t\tlogrus.FieldKeyLevel: \"severity\",\n\t\t\tlogrus.FieldKeyMsg:   \"message\",\n\t\t},\n\t\tTimestampFormat: time.RFC3339Nano,\n\t}\n\tlog.Out = os.Stdout\n\tcatalogMutex = &sync.Mutex{}\n\terr := readCatalogFile(&cat)\n\tif err != nil {\n\t\tlog.Warnf(\"could not parse product catalog\")\n\t}\n}\n\nfunc main() {\n\tif os.Getenv(\"DISABLE_TRACING\") == \"\" {\n\t\tlog.Info(\"Tracing enabled.\")\n\t\tgo initTracing()\n\t} else {\n\t\tlog.Info(\"Tracing disabled.\")\n\t}\n\n\tif os.Getenv(\"DISABLE_PROFILER\") == \"\" {\n\t\tlog.Info(\"Profiling enabled.\")\n\t\tgo initProfiling(\"productcatalogservice\", \"1.0.0\")\n\t} else {\n\t\tlog.Info(\"Profiling disabled.\")\n\t}\n\n\tflag.Parse()\n\n\t// set injected latency\n\tif s := os.Getenv(\"EXTRA_LATENCY\"); s != \"\" {\n\t\tv, err := time.ParseDuration(s)\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"failed to parse EXTRA_LATENCY (%s) as time.Duration: %+v\", v, err)\n\t\t}\n\t\textraLatency = v\n\t\tlog.Infof(\"extra latency enabled (duration: %v)\", extraLatency)\n\t} else {\n\t\textraLatency = time.Duration(0)\n\t}\n\n\tsigs := make(chan os.Signal, 1)\n\tsignal.Notify(sigs, syscall.SIGUSR1, syscall.SIGUSR2)\n\tgo func() {\n\t\tfor {\n\t\t\tsig := <-sigs\n\t\t\tlog.Printf(\"Received signal: %s\", sig)\n\t\t\tif sig == syscall.SIGUSR1 {\n\t\t\t\treloadCatalog = true\n\t\t\t\tlog.Infof(\"Enable catalog reloading\")\n\t\t\t} else {\n\t\t\t\treloadCatalog = false\n\t\t\t\tlog.Infof(\"Disable catalog reloading\")\n\t\t\t}\n\t\t}\n\t}()\n\n\tif os.Getenv(\"PORT\") != \"\" {\n\t\tport = os.Getenv(\"PORT\")\n\t}\n\tlog.Infof(\"starting grpc server at :%s\", port)\n\trun(port)\n\tselect {}\n}\n\nfunc run(port string) string {\n\tl, err := net.Listen(\"tcp\", fmt.Sprintf(\":%s\", port))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tvar srv *grpc.Server\n\tif os.Getenv(\"DISABLE_STATS\") == \"\" {\n\t\tlog.Info(\"Stats enabled.\")\n\t\tsrv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))\n\t} else {\n\t\tlog.Info(\"Stats disabled.\")\n\t\tsrv = grpc.NewServer()\n\t}\n\n\tsvc := &productCatalog{}\n\n\tpb.RegisterProductCatalogServiceServer(srv, svc)\n\thealthpb.RegisterHealthServer(srv, svc)\n\tgo srv.Serve(l)\n\treturn l.Addr().String()\n}\n\nfunc initJaegerTracing() {\n\tsvcAddr := os.Getenv(\"JAEGER_SERVICE_ADDR\")\n\tif svcAddr == \"\" {\n\t\tlog.Info(\"jaeger initialization disabled.\")\n\t\treturn\n\t}\n\t// Register the Jaeger exporter to be able to retrieve\n\t// the collected spans.\n\texporter, err := jaeger.NewExporter(jaeger.Options{\n\t\tEndpoint: fmt.Sprintf(\"http://%s\", svcAddr),\n\t\tProcess: jaeger.Process{\n\t\t\tServiceName: \"productcatalogservice\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\ttrace.RegisterExporter(exporter)\n\tlog.Info(\"jaeger initialization completed.\")\n}\n\nfunc initStats(exporter *stackdriver.Exporter) {\n\tview.SetReportingPeriod(60 * time.Second)\n\tview.RegisterExporter(exporter)\n\tif err := view.Register(ocgrpc.DefaultServerViews...); err != nil {\n\t\tlog.Info(\"Error registering default server views\")\n\t} else {\n\t\tlog.Info(\"Registered default server views\")\n\t}\n}\n\nfunc initStackdriverTracing() {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\texporter, err := stackdriver.NewExporter(stackdriver.Options{})\n\t\tif err != nil {\n\t\t\tlog.Warnf(\"failed to initialize Stackdriver exporter: %+v\", err)\n\t\t} else {\n\t\t\ttrace.RegisterExporter(exporter)\n\t\t\ttrace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})\n\t\t\tlog.Info(\"registered Stackdriver tracing\")\n\n\t\t\t// Register the views to collect server stats.\n\t\t\tinitStats(exporter)\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver exporter\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver exporter after retrying, giving up\")\n}\n\nfunc initTracing() {\n\tinitJaegerTracing()\n\tinitStackdriverTracing()\n}\n\nfunc initProfiling(service, version string) {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\tif err := profiler.Start(profiler.Config{\n\t\t\tService:        service,\n\t\t\tServiceVersion: version,\n\t\t\t// ProjectID must be set if not running on GCP.\n\t\t\t// ProjectID: \"my-project\",\n\t\t}); err != nil {\n\t\t\tlog.Warnf(\"failed to start profiler: %+v\", err)\n\t\t} else {\n\t\t\tlog.Info(\"started Stackdriver profiler\")\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver profiler\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver profiler after retrying, giving up\")\n}\n\ntype productCatalog struct{}\n\nfunc readCatalogFile(catalog *pb.ListProductsResponse) error {\n\tcatalogMutex.Lock()\n\tdefer catalogMutex.Unlock()\n\tcatalogJSON, err := ioutil.ReadFile(\"products.json\")\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to open product catalog json file: %v\", err)\n\t\treturn err\n\t}\n\tif err := jsonpb.Unmarshal(bytes.NewReader(catalogJSON), catalog); err != nil {\n\t\tlog.Warnf(\"failed to parse the catalog JSON: %v\", err)\n\t\treturn err\n\t}\n\tlog.Info(\"successfully parsed product catalog json\")\n\treturn nil\n}\n\nfunc parseCatalog() []*pb.Product {\n\tif reloadCatalog || len(cat.Products) == 0 {\n\t\terr := readCatalogFile(&cat)\n\t\tif err != nil {\n\t\t\treturn []*pb.Product{}\n\t\t}\n\t}\n\treturn cat.Products\n}\n\nfunc (p *productCatalog) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {\n\treturn &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil\n}\n\nfunc (p *productCatalog) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error {\n\treturn status.Errorf(codes.Unimplemented, \"health check via Watch not implemented\")\n}\n\nfunc (p *productCatalog) ListProducts(context.Context, *pb.Empty) (*pb.ListProductsResponse, error) {\n\ttime.Sleep(extraLatency)\n\treturn &pb.ListProductsResponse{Products: parseCatalog()}, nil\n}\n\nfunc (p *productCatalog) GetProduct(ctx context.Context, req *pb.GetProductRequest) (*pb.Product, error) {\n\ttime.Sleep(extraLatency)\n\tvar found *pb.Product\n\tfor i := 0; i < len(parseCatalog()); i++ {\n\t\tif req.Id == parseCatalog()[i].Id {\n\t\t\tfound = parseCatalog()[i]\n\t\t}\n\t}\n\tif found == nil {\n\t\treturn nil, status.Errorf(codes.NotFound, \"no product with ID %s\", req.Id)\n\t}\n\treturn found, nil\n}\n\nfunc (p *productCatalog) SearchProducts(ctx context.Context, req *pb.SearchProductsRequest) (*pb.SearchProductsResponse, error) {\n\ttime.Sleep(extraLatency)\n\t// Intepret query as a substring match in name or description.\n\tvar ps []*pb.Product\n\tfor _, p := range parseCatalog() {\n\t\tif strings.Contains(strings.ToLower(p.Name), strings.ToLower(req.Query)) ||\n\t\t\tstrings.Contains(strings.ToLower(p.Description), strings.ToLower(req.Query)) {\n\t\t\tps = append(ps, p)\n\t\t}\n\t}\n\treturn &pb.SearchProductsResponse{Results: ps}, nil\n}\n"
  },
  {
    "path": "microservices-demo/src/productcatalogservice/server_test.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"context\"\n\t\"testing\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/productcatalogservice/genproto\"\n\t\"github.com/golang/protobuf/proto\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"go.opencensus.io/plugin/ocgrpc\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/status\"\n)\n\nfunc TestServer(t *testing.T) {\n\tctx := context.Background()\n\taddr := run(port)\n\tconn, err := grpc.DialContext(ctx, addr,\n\t\tgrpc.WithInsecure(),\n\t\tgrpc.WithStatsHandler(&ocgrpc.ClientHandler{}))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer conn.Close()\n\tclient := pb.NewProductCatalogServiceClient(conn)\n\tres, err := client.ListProducts(ctx, &pb.Empty{})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff := cmp.Diff(res.Products, parseCatalog(), cmp.Comparer(proto.Equal)); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n\n\tgot, err := client.GetProduct(ctx, &pb.GetProductRequest{Id: \"OLJCESPC7Z\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif want := parseCatalog()[0]; !proto.Equal(got, want) {\n\t\tt.Errorf(\"got %v, want %v\", got, want)\n\t}\n\t_, err = client.GetProduct(ctx, &pb.GetProductRequest{Id: \"N/A\"})\n\tif got, want := status.Code(err), codes.NotFound; got != want {\n\t\tt.Errorf(\"got %s, want %s\", got, want)\n\t}\n\n\tsres, err := client.SearchProducts(ctx, &pb.SearchProductsRequest{Query: \"sunglasses\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif diff := cmp.Diff(sres.Results, []*pb.Product{parseCatalog()[0]}, cmp.Comparer(proto.Equal)); diff != \"\" {\n\t\tt.Error(diff)\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/.gitignore",
    "content": "*.pyc\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/.python-version",
    "content": "3.7\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM python:3.7-slim\nRUN apt-get update -qqy && \\\n\tapt-get -qqy install wget g++ && \\\n\trm -rf /var/lib/apt/lists/*\n# show python logs as they occur\nENV PYTHONUNBUFFERED=0\n\n# download the grpc health probe\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\n\n# get packages\nWORKDIR /recommendationservice\nCOPY requirements.txt requirements.txt\nRUN pip install -r requirements.txt\n\n# add files into working directory\nCOPY . .\n\n# set listen port\nENV PORT \"8080\"\nEXPOSE 8080\n\nENTRYPOINT [\"python\", \"/recommendationservice/recommendation_server.py\"]\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/Procfile",
    "content": "web: python /recommendationservice/recommendation_server.py\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/client.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport sys\nimport grpc\nimport demo_pb2\nimport demo_pb2_grpc\n\nfrom opencensus.trace.tracer import Tracer\nfrom opencensus.trace.exporters import stackdriver_exporter\nfrom opencensus.trace.ext.grpc import client_interceptor\n\nfrom logger import getJSONLogger\nlogger = getJSONLogger('recommendationservice-server')\n\nif __name__ == \"__main__\":\n    # get port\n    if len(sys.argv) > 1:\n        port = sys.argv[1]\n    else:\n        port = \"8080\"\n\n    try:\n        exporter = stackdriver_exporter.StackdriverExporter()\n        tracer = Tracer(exporter=exporter)\n        tracer_interceptor = client_interceptor.OpenCensusClientInterceptor(tracer, host_port='localhost:'+port)\n    except:\n        tracer_interceptor = client_interceptor.OpenCensusClientInterceptor()\n\n    # set up server stub\n    channel = grpc.insecure_channel('localhost:'+port)\n    channel = grpc.intercept_channel(channel, tracer_interceptor)\n    stub = demo_pb2_grpc.RecommendationServiceStub(channel)\n    # form request\n    request = demo_pb2.ListRecommendationsRequest(user_id=\"test\", product_ids=[\"test\"])\n    # make call to server\n    response = stub.ListRecommendations(request)\n    logger.info(response)\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/demo_pb2.py",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Generated by the protocol buffer compiler.  DO NOT EDIT!\n# source: demo.proto\n\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))\nfrom google.protobuf import descriptor as _descriptor\nfrom google.protobuf import message as _message\nfrom google.protobuf import reflection as _reflection\nfrom google.protobuf import symbol_database as _symbol_database\nfrom google.protobuf import descriptor_pb2\n# @@protoc_insertion_point(imports)\n\n_sym_db = _symbol_database.Default()\n\n\n\n\nDESCRIPTOR = _descriptor.FileDescriptor(\n  name='demo.proto',\n  package='hipstershop',\n  syntax='proto3',\n  serialized_pb=_b('\\n\\ndemo.proto\\x12\\x0bhipstershop\\\"0\\n\\x08\\x43\\x61rtItem\\x12\\x12\\n\\nproduct_id\\x18\\x01 \\x01(\\t\\x12\\x10\\n\\x08quantity\\x18\\x02 \\x01(\\x05\\\"F\\n\\x0e\\x41\\x64\\x64ItemRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12#\\n\\x04item\\x18\\x02 \\x01(\\x0b\\x32\\x15.hipstershop.CartItem\\\"#\\n\\x10\\x45mptyCartRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\\"!\\n\\x0eGetCartRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\\"=\\n\\x04\\x43\\x61rt\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"\\x07\\n\\x05\\x45mpty\\\"B\\n\\x1aListRecommendationsRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12\\x13\\n\\x0bproduct_ids\\x18\\x02 \\x03(\\t\\\"2\\n\\x1bListRecommendationsResponse\\x12\\x13\\n\\x0bproduct_ids\\x18\\x01 \\x03(\\t\\\"p\\n\\x07Product\\x12\\n\\n\\x02id\\x18\\x01 \\x01(\\t\\x12\\x0c\\n\\x04name\\x18\\x02 \\x01(\\t\\x12\\x13\\n\\x0b\\x64\\x65scription\\x18\\x03 \\x01(\\t\\x12\\x0f\\n\\x07picture\\x18\\x04 \\x01(\\t\\x12%\\n\\tprice_usd\\x18\\x05 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\">\\n\\x14ListProductsResponse\\x12&\\n\\x08products\\x18\\x01 \\x03(\\x0b\\x32\\x14.hipstershop.Product\\\"\\x1f\\n\\x11GetProductRequest\\x12\\n\\n\\x02id\\x18\\x01 \\x01(\\t\\\"&\\n\\x15SearchProductsRequest\\x12\\r\\n\\x05query\\x18\\x01 \\x01(\\t\\\"?\\n\\x16SearchProductsResponse\\x12%\\n\\x07results\\x18\\x01 \\x03(\\x0b\\x32\\x14.hipstershop.Product\\\"^\\n\\x0fGetQuoteRequest\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x01 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"8\\n\\x10GetQuoteResponse\\x12$\\n\\x08\\x63ost_usd\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\"_\\n\\x10ShipOrderRequest\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x01 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12$\\n\\x05items\\x18\\x02 \\x03(\\x0b\\x32\\x15.hipstershop.CartItem\\\"(\\n\\x11ShipOrderResponse\\x12\\x13\\n\\x0btracking_id\\x18\\x01 \\x01(\\t\\\"a\\n\\x07\\x41\\x64\\x64ress\\x12\\x16\\n\\x0estreet_address\\x18\\x01 \\x01(\\t\\x12\\x0c\\n\\x04\\x63ity\\x18\\x02 \\x01(\\t\\x12\\r\\n\\x05state\\x18\\x03 \\x01(\\t\\x12\\x0f\\n\\x07\\x63ountry\\x18\\x04 \\x01(\\t\\x12\\x10\\n\\x08zip_code\\x18\\x05 \\x01(\\x05\\\"<\\n\\x05Money\\x12\\x15\\n\\rcurrency_code\\x18\\x01 \\x01(\\t\\x12\\r\\n\\x05units\\x18\\x02 \\x01(\\x03\\x12\\r\\n\\x05nanos\\x18\\x03 \\x01(\\x05\\\"8\\n\\x1eGetSupportedCurrenciesResponse\\x12\\x16\\n\\x0e\\x63urrency_codes\\x18\\x01 \\x03(\\t\\\"N\\n\\x19\\x43urrencyConversionRequest\\x12 \\n\\x04\\x66rom\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12\\x0f\\n\\x07to_code\\x18\\x02 \\x01(\\t\\\"\\x90\\x01\\n\\x0e\\x43reditCardInfo\\x12\\x1a\\n\\x12\\x63redit_card_number\\x18\\x01 \\x01(\\t\\x12\\x17\\n\\x0f\\x63redit_card_cvv\\x18\\x02 \\x01(\\x05\\x12#\\n\\x1b\\x63redit_card_expiration_year\\x18\\x03 \\x01(\\x05\\x12$\\n\\x1c\\x63redit_card_expiration_month\\x18\\x04 \\x01(\\x05\\\"e\\n\\rChargeRequest\\x12\\\"\\n\\x06\\x61mount\\x18\\x01 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12\\x30\\n\\x0b\\x63redit_card\\x18\\x02 \\x01(\\x0b\\x32\\x1b.hipstershop.CreditCardInfo\\\"(\\n\\x0e\\x43hargeResponse\\x12\\x16\\n\\x0etransaction_id\\x18\\x01 \\x01(\\t\\\"R\\n\\tOrderItem\\x12#\\n\\x04item\\x18\\x01 \\x01(\\x0b\\x32\\x15.hipstershop.CartItem\\x12 \\n\\x04\\x63ost\\x18\\x02 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\\"\\xbf\\x01\\n\\x0bOrderResult\\x12\\x10\\n\\x08order_id\\x18\\x01 \\x01(\\t\\x12\\x1c\\n\\x14shipping_tracking_id\\x18\\x02 \\x01(\\t\\x12)\\n\\rshipping_cost\\x18\\x03 \\x01(\\x0b\\x32\\x12.hipstershop.Money\\x12.\\n\\x10shipping_address\\x18\\x04 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12%\\n\\x05items\\x18\\x05 \\x03(\\x0b\\x32\\x16.hipstershop.OrderItem\\\"V\\n\\x1cSendOrderConfirmationRequest\\x12\\r\\n\\x05\\x65mail\\x18\\x01 \\x01(\\t\\x12\\'\\n\\x05order\\x18\\x02 \\x01(\\x0b\\x32\\x18.hipstershop.OrderResult\\\"\\xa3\\x01\\n\\x11PlaceOrderRequest\\x12\\x0f\\n\\x07user_id\\x18\\x01 \\x01(\\t\\x12\\x15\\n\\ruser_currency\\x18\\x02 \\x01(\\t\\x12%\\n\\x07\\x61\\x64\\x64ress\\x18\\x03 \\x01(\\x0b\\x32\\x14.hipstershop.Address\\x12\\r\\n\\x05\\x65mail\\x18\\x05 \\x01(\\t\\x12\\x30\\n\\x0b\\x63redit_card\\x18\\x06 \\x01(\\x0b\\x32\\x1b.hipstershop.CreditCardInfo\\\"=\\n\\x12PlaceOrderResponse\\x12\\'\\n\\x05order\\x18\\x01 \\x01(\\x0b\\x32\\x18.hipstershop.OrderResult\\\"\\\"\\n\\nAdsRequest\\x12\\x14\\n\\x0c\\x63ontext_keys\\x18\\x01 \\x03(\\t\\\"+\\n\\x0b\\x41\\x64sResponse\\x12\\x1c\\n\\x03\\x61\\x64s\\x18\\x01 \\x03(\\x0b\\x32\\x0f.hipstershop.Ad\\\"(\\n\\x02\\x41\\x64\\x12\\x14\\n\\x0credirect_url\\x18\\x01 \\x01(\\t\\x12\\x0c\\n\\x04text\\x18\\x02 \\x01(\\t2\\xca\\x01\\n\\x0b\\x43\\x61rtService\\x12<\\n\\x07\\x41\\x64\\x64Item\\x12\\x1b.hipstershop.AddItemRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x12;\\n\\x07GetCart\\x12\\x1b.hipstershop.GetCartRequest\\x1a\\x11.hipstershop.Cart\\\"\\x00\\x12@\\n\\tEmptyCart\\x12\\x1d.hipstershop.EmptyCartRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x32\\x83\\x01\\n\\x15RecommendationService\\x12j\\n\\x13ListRecommendations\\x12\\'.hipstershop.ListRecommendationsRequest\\x1a(.hipstershop.ListRecommendationsResponse\\\"\\x00\\x32\\x83\\x02\\n\\x15ProductCatalogService\\x12G\\n\\x0cListProducts\\x12\\x12.hipstershop.Empty\\x1a!.hipstershop.ListProductsResponse\\\"\\x00\\x12\\x44\\n\\nGetProduct\\x12\\x1e.hipstershop.GetProductRequest\\x1a\\x14.hipstershop.Product\\\"\\x00\\x12[\\n\\x0eSearchProducts\\x12\\\".hipstershop.SearchProductsRequest\\x1a#.hipstershop.SearchProductsResponse\\\"\\x00\\x32\\xaa\\x01\\n\\x0fShippingService\\x12I\\n\\x08GetQuote\\x12\\x1c.hipstershop.GetQuoteRequest\\x1a\\x1d.hipstershop.GetQuoteResponse\\\"\\x00\\x12L\\n\\tShipOrder\\x12\\x1d.hipstershop.ShipOrderRequest\\x1a\\x1e.hipstershop.ShipOrderResponse\\\"\\x00\\x32\\xb7\\x01\\n\\x0f\\x43urrencyService\\x12[\\n\\x16GetSupportedCurrencies\\x12\\x12.hipstershop.Empty\\x1a+.hipstershop.GetSupportedCurrenciesResponse\\\"\\x00\\x12G\\n\\x07\\x43onvert\\x12&.hipstershop.CurrencyConversionRequest\\x1a\\x12.hipstershop.Money\\\"\\x00\\x32U\\n\\x0ePaymentService\\x12\\x43\\n\\x06\\x43harge\\x12\\x1a.hipstershop.ChargeRequest\\x1a\\x1b.hipstershop.ChargeResponse\\\"\\x00\\x32h\\n\\x0c\\x45mailService\\x12X\\n\\x15SendOrderConfirmation\\x12).hipstershop.SendOrderConfirmationRequest\\x1a\\x12.hipstershop.Empty\\\"\\x00\\x32\\x62\\n\\x0f\\x43heckoutService\\x12O\\n\\nPlaceOrder\\x12\\x1e.hipstershop.PlaceOrderRequest\\x1a\\x1f.hipstershop.PlaceOrderResponse\\\"\\x00\\x32K\\n\\nAdsService\\x12=\\n\\x06GetAds\\x12\\x17.hipstershop.AdsRequest\\x1a\\x18.hipstershop.AdsResponse\\\"\\x00\\x62\\x06proto3')\n)\n\n\n\n\n_CARTITEM = _descriptor.Descriptor(\n  name='CartItem',\n  full_name='hipstershop.CartItem',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='product_id', full_name='hipstershop.CartItem.product_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='quantity', full_name='hipstershop.CartItem.quantity', index=1,\n      number=2, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=27,\n  serialized_end=75,\n)\n\n\n_ADDITEMREQUEST = _descriptor.Descriptor(\n  name='AddItemRequest',\n  full_name='hipstershop.AddItemRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.AddItemRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='item', full_name='hipstershop.AddItemRequest.item', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=77,\n  serialized_end=147,\n)\n\n\n_EMPTYCARTREQUEST = _descriptor.Descriptor(\n  name='EmptyCartRequest',\n  full_name='hipstershop.EmptyCartRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.EmptyCartRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=149,\n  serialized_end=184,\n)\n\n\n_GETCARTREQUEST = _descriptor.Descriptor(\n  name='GetCartRequest',\n  full_name='hipstershop.GetCartRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.GetCartRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=186,\n  serialized_end=219,\n)\n\n\n_CART = _descriptor.Descriptor(\n  name='Cart',\n  full_name='hipstershop.Cart',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.Cart.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.Cart.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=221,\n  serialized_end=282,\n)\n\n\n_EMPTY = _descriptor.Descriptor(\n  name='Empty',\n  full_name='hipstershop.Empty',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=284,\n  serialized_end=291,\n)\n\n\n_LISTRECOMMENDATIONSREQUEST = _descriptor.Descriptor(\n  name='ListRecommendationsRequest',\n  full_name='hipstershop.ListRecommendationsRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.ListRecommendationsRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='product_ids', full_name='hipstershop.ListRecommendationsRequest.product_ids', index=1,\n      number=2, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=293,\n  serialized_end=359,\n)\n\n\n_LISTRECOMMENDATIONSRESPONSE = _descriptor.Descriptor(\n  name='ListRecommendationsResponse',\n  full_name='hipstershop.ListRecommendationsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='product_ids', full_name='hipstershop.ListRecommendationsResponse.product_ids', index=0,\n      number=1, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=361,\n  serialized_end=411,\n)\n\n\n_PRODUCT = _descriptor.Descriptor(\n  name='Product',\n  full_name='hipstershop.Product',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='id', full_name='hipstershop.Product.id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='name', full_name='hipstershop.Product.name', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='description', full_name='hipstershop.Product.description', index=2,\n      number=3, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='picture', full_name='hipstershop.Product.picture', index=3,\n      number=4, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='price_usd', full_name='hipstershop.Product.price_usd', index=4,\n      number=5, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=413,\n  serialized_end=525,\n)\n\n\n_LISTPRODUCTSRESPONSE = _descriptor.Descriptor(\n  name='ListProductsResponse',\n  full_name='hipstershop.ListProductsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='products', full_name='hipstershop.ListProductsResponse.products', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=527,\n  serialized_end=589,\n)\n\n\n_GETPRODUCTREQUEST = _descriptor.Descriptor(\n  name='GetProductRequest',\n  full_name='hipstershop.GetProductRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='id', full_name='hipstershop.GetProductRequest.id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=591,\n  serialized_end=622,\n)\n\n\n_SEARCHPRODUCTSREQUEST = _descriptor.Descriptor(\n  name='SearchProductsRequest',\n  full_name='hipstershop.SearchProductsRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='query', full_name='hipstershop.SearchProductsRequest.query', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=624,\n  serialized_end=662,\n)\n\n\n_SEARCHPRODUCTSRESPONSE = _descriptor.Descriptor(\n  name='SearchProductsResponse',\n  full_name='hipstershop.SearchProductsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='results', full_name='hipstershop.SearchProductsResponse.results', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=664,\n  serialized_end=727,\n)\n\n\n_GETQUOTEREQUEST = _descriptor.Descriptor(\n  name='GetQuoteRequest',\n  full_name='hipstershop.GetQuoteRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.GetQuoteRequest.address', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.GetQuoteRequest.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=729,\n  serialized_end=823,\n)\n\n\n_GETQUOTERESPONSE = _descriptor.Descriptor(\n  name='GetQuoteResponse',\n  full_name='hipstershop.GetQuoteResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='cost_usd', full_name='hipstershop.GetQuoteResponse.cost_usd', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=825,\n  serialized_end=881,\n)\n\n\n_SHIPORDERREQUEST = _descriptor.Descriptor(\n  name='ShipOrderRequest',\n  full_name='hipstershop.ShipOrderRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.ShipOrderRequest.address', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.ShipOrderRequest.items', index=1,\n      number=2, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=883,\n  serialized_end=978,\n)\n\n\n_SHIPORDERRESPONSE = _descriptor.Descriptor(\n  name='ShipOrderResponse',\n  full_name='hipstershop.ShipOrderResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='tracking_id', full_name='hipstershop.ShipOrderResponse.tracking_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=980,\n  serialized_end=1020,\n)\n\n\n_ADDRESS = _descriptor.Descriptor(\n  name='Address',\n  full_name='hipstershop.Address',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='street_address', full_name='hipstershop.Address.street_address', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='city', full_name='hipstershop.Address.city', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='state', full_name='hipstershop.Address.state', index=2,\n      number=3, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='country', full_name='hipstershop.Address.country', index=3,\n      number=4, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='zip_code', full_name='hipstershop.Address.zip_code', index=4,\n      number=5, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1022,\n  serialized_end=1119,\n)\n\n\n_MONEY = _descriptor.Descriptor(\n  name='Money',\n  full_name='hipstershop.Money',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='currency_code', full_name='hipstershop.Money.currency_code', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='units', full_name='hipstershop.Money.units', index=1,\n      number=2, type=3, cpp_type=2, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='nanos', full_name='hipstershop.Money.nanos', index=2,\n      number=3, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1121,\n  serialized_end=1181,\n)\n\n\n_GETSUPPORTEDCURRENCIESRESPONSE = _descriptor.Descriptor(\n  name='GetSupportedCurrenciesResponse',\n  full_name='hipstershop.GetSupportedCurrenciesResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='currency_codes', full_name='hipstershop.GetSupportedCurrenciesResponse.currency_codes', index=0,\n      number=1, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1183,\n  serialized_end=1239,\n)\n\n\n_CURRENCYCONVERSIONREQUEST = _descriptor.Descriptor(\n  name='CurrencyConversionRequest',\n  full_name='hipstershop.CurrencyConversionRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='from', full_name='hipstershop.CurrencyConversionRequest.from', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='to_code', full_name='hipstershop.CurrencyConversionRequest.to_code', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1241,\n  serialized_end=1319,\n)\n\n\n_CREDITCARDINFO = _descriptor.Descriptor(\n  name='CreditCardInfo',\n  full_name='hipstershop.CreditCardInfo',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='credit_card_number', full_name='hipstershop.CreditCardInfo.credit_card_number', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_cvv', full_name='hipstershop.CreditCardInfo.credit_card_cvv', index=1,\n      number=2, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_expiration_year', full_name='hipstershop.CreditCardInfo.credit_card_expiration_year', index=2,\n      number=3, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card_expiration_month', full_name='hipstershop.CreditCardInfo.credit_card_expiration_month', index=3,\n      number=4, type=5, cpp_type=1, label=1,\n      has_default_value=False, default_value=0,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1322,\n  serialized_end=1466,\n)\n\n\n_CHARGEREQUEST = _descriptor.Descriptor(\n  name='ChargeRequest',\n  full_name='hipstershop.ChargeRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='amount', full_name='hipstershop.ChargeRequest.amount', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card', full_name='hipstershop.ChargeRequest.credit_card', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1468,\n  serialized_end=1569,\n)\n\n\n_CHARGERESPONSE = _descriptor.Descriptor(\n  name='ChargeResponse',\n  full_name='hipstershop.ChargeResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='transaction_id', full_name='hipstershop.ChargeResponse.transaction_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1571,\n  serialized_end=1611,\n)\n\n\n_ORDERITEM = _descriptor.Descriptor(\n  name='OrderItem',\n  full_name='hipstershop.OrderItem',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='item', full_name='hipstershop.OrderItem.item', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='cost', full_name='hipstershop.OrderItem.cost', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1613,\n  serialized_end=1695,\n)\n\n\n_ORDERRESULT = _descriptor.Descriptor(\n  name='OrderResult',\n  full_name='hipstershop.OrderResult',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='order_id', full_name='hipstershop.OrderResult.order_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_tracking_id', full_name='hipstershop.OrderResult.shipping_tracking_id', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_cost', full_name='hipstershop.OrderResult.shipping_cost', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='shipping_address', full_name='hipstershop.OrderResult.shipping_address', index=3,\n      number=4, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='items', full_name='hipstershop.OrderResult.items', index=4,\n      number=5, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1698,\n  serialized_end=1889,\n)\n\n\n_SENDORDERCONFIRMATIONREQUEST = _descriptor.Descriptor(\n  name='SendOrderConfirmationRequest',\n  full_name='hipstershop.SendOrderConfirmationRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='email', full_name='hipstershop.SendOrderConfirmationRequest.email', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='order', full_name='hipstershop.SendOrderConfirmationRequest.order', index=1,\n      number=2, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1891,\n  serialized_end=1977,\n)\n\n\n_PLACEORDERREQUEST = _descriptor.Descriptor(\n  name='PlaceOrderRequest',\n  full_name='hipstershop.PlaceOrderRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='user_id', full_name='hipstershop.PlaceOrderRequest.user_id', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='user_currency', full_name='hipstershop.PlaceOrderRequest.user_currency', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='address', full_name='hipstershop.PlaceOrderRequest.address', index=2,\n      number=3, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='email', full_name='hipstershop.PlaceOrderRequest.email', index=3,\n      number=5, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='credit_card', full_name='hipstershop.PlaceOrderRequest.credit_card', index=4,\n      number=6, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=1980,\n  serialized_end=2143,\n)\n\n\n_PLACEORDERRESPONSE = _descriptor.Descriptor(\n  name='PlaceOrderResponse',\n  full_name='hipstershop.PlaceOrderResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='order', full_name='hipstershop.PlaceOrderResponse.order', index=0,\n      number=1, type=11, cpp_type=10, label=1,\n      has_default_value=False, default_value=None,\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2145,\n  serialized_end=2206,\n)\n\n\n_ADSREQUEST = _descriptor.Descriptor(\n  name='AdsRequest',\n  full_name='hipstershop.AdsRequest',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='context_keys', full_name='hipstershop.AdsRequest.context_keys', index=0,\n      number=1, type=9, cpp_type=9, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2208,\n  serialized_end=2242,\n)\n\n\n_ADSRESPONSE = _descriptor.Descriptor(\n  name='AdsResponse',\n  full_name='hipstershop.AdsResponse',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='ads', full_name='hipstershop.AdsResponse.ads', index=0,\n      number=1, type=11, cpp_type=10, label=3,\n      has_default_value=False, default_value=[],\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2244,\n  serialized_end=2287,\n)\n\n\n_AD = _descriptor.Descriptor(\n  name='Ad',\n  full_name='hipstershop.Ad',\n  filename=None,\n  file=DESCRIPTOR,\n  containing_type=None,\n  fields=[\n    _descriptor.FieldDescriptor(\n      name='redirect_url', full_name='hipstershop.Ad.redirect_url', index=0,\n      number=1, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n    _descriptor.FieldDescriptor(\n      name='text', full_name='hipstershop.Ad.text', index=1,\n      number=2, type=9, cpp_type=9, label=1,\n      has_default_value=False, default_value=_b(\"\").decode('utf-8'),\n      message_type=None, enum_type=None, containing_type=None,\n      is_extension=False, extension_scope=None,\n      options=None, file=DESCRIPTOR),\n  ],\n  extensions=[\n  ],\n  nested_types=[],\n  enum_types=[\n  ],\n  options=None,\n  is_extendable=False,\n  syntax='proto3',\n  extension_ranges=[],\n  oneofs=[\n  ],\n  serialized_start=2289,\n  serialized_end=2329,\n)\n\n_ADDITEMREQUEST.fields_by_name['item'].message_type = _CARTITEM\n_CART.fields_by_name['items'].message_type = _CARTITEM\n_PRODUCT.fields_by_name['price_usd'].message_type = _MONEY\n_LISTPRODUCTSRESPONSE.fields_by_name['products'].message_type = _PRODUCT\n_SEARCHPRODUCTSRESPONSE.fields_by_name['results'].message_type = _PRODUCT\n_GETQUOTEREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_GETQUOTEREQUEST.fields_by_name['items'].message_type = _CARTITEM\n_GETQUOTERESPONSE.fields_by_name['cost_usd'].message_type = _MONEY\n_SHIPORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_SHIPORDERREQUEST.fields_by_name['items'].message_type = _CARTITEM\n_CURRENCYCONVERSIONREQUEST.fields_by_name['from'].message_type = _MONEY\n_CHARGEREQUEST.fields_by_name['amount'].message_type = _MONEY\n_CHARGEREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO\n_ORDERITEM.fields_by_name['item'].message_type = _CARTITEM\n_ORDERITEM.fields_by_name['cost'].message_type = _MONEY\n_ORDERRESULT.fields_by_name['shipping_cost'].message_type = _MONEY\n_ORDERRESULT.fields_by_name['shipping_address'].message_type = _ADDRESS\n_ORDERRESULT.fields_by_name['items'].message_type = _ORDERITEM\n_SENDORDERCONFIRMATIONREQUEST.fields_by_name['order'].message_type = _ORDERRESULT\n_PLACEORDERREQUEST.fields_by_name['address'].message_type = _ADDRESS\n_PLACEORDERREQUEST.fields_by_name['credit_card'].message_type = _CREDITCARDINFO\n_PLACEORDERRESPONSE.fields_by_name['order'].message_type = _ORDERRESULT\n_ADSRESPONSE.fields_by_name['ads'].message_type = _AD\nDESCRIPTOR.message_types_by_name['CartItem'] = _CARTITEM\nDESCRIPTOR.message_types_by_name['AddItemRequest'] = _ADDITEMREQUEST\nDESCRIPTOR.message_types_by_name['EmptyCartRequest'] = _EMPTYCARTREQUEST\nDESCRIPTOR.message_types_by_name['GetCartRequest'] = _GETCARTREQUEST\nDESCRIPTOR.message_types_by_name['Cart'] = _CART\nDESCRIPTOR.message_types_by_name['Empty'] = _EMPTY\nDESCRIPTOR.message_types_by_name['ListRecommendationsRequest'] = _LISTRECOMMENDATIONSREQUEST\nDESCRIPTOR.message_types_by_name['ListRecommendationsResponse'] = _LISTRECOMMENDATIONSRESPONSE\nDESCRIPTOR.message_types_by_name['Product'] = _PRODUCT\nDESCRIPTOR.message_types_by_name['ListProductsResponse'] = _LISTPRODUCTSRESPONSE\nDESCRIPTOR.message_types_by_name['GetProductRequest'] = _GETPRODUCTREQUEST\nDESCRIPTOR.message_types_by_name['SearchProductsRequest'] = _SEARCHPRODUCTSREQUEST\nDESCRIPTOR.message_types_by_name['SearchProductsResponse'] = _SEARCHPRODUCTSRESPONSE\nDESCRIPTOR.message_types_by_name['GetQuoteRequest'] = _GETQUOTEREQUEST\nDESCRIPTOR.message_types_by_name['GetQuoteResponse'] = _GETQUOTERESPONSE\nDESCRIPTOR.message_types_by_name['ShipOrderRequest'] = _SHIPORDERREQUEST\nDESCRIPTOR.message_types_by_name['ShipOrderResponse'] = _SHIPORDERRESPONSE\nDESCRIPTOR.message_types_by_name['Address'] = _ADDRESS\nDESCRIPTOR.message_types_by_name['Money'] = _MONEY\nDESCRIPTOR.message_types_by_name['GetSupportedCurrenciesResponse'] = _GETSUPPORTEDCURRENCIESRESPONSE\nDESCRIPTOR.message_types_by_name['CurrencyConversionRequest'] = _CURRENCYCONVERSIONREQUEST\nDESCRIPTOR.message_types_by_name['CreditCardInfo'] = _CREDITCARDINFO\nDESCRIPTOR.message_types_by_name['ChargeRequest'] = _CHARGEREQUEST\nDESCRIPTOR.message_types_by_name['ChargeResponse'] = _CHARGERESPONSE\nDESCRIPTOR.message_types_by_name['OrderItem'] = _ORDERITEM\nDESCRIPTOR.message_types_by_name['OrderResult'] = _ORDERRESULT\nDESCRIPTOR.message_types_by_name['SendOrderConfirmationRequest'] = _SENDORDERCONFIRMATIONREQUEST\nDESCRIPTOR.message_types_by_name['PlaceOrderRequest'] = _PLACEORDERREQUEST\nDESCRIPTOR.message_types_by_name['PlaceOrderResponse'] = _PLACEORDERRESPONSE\nDESCRIPTOR.message_types_by_name['AdsRequest'] = _ADSREQUEST\nDESCRIPTOR.message_types_by_name['AdsResponse'] = _ADSRESPONSE\nDESCRIPTOR.message_types_by_name['Ad'] = _AD\n_sym_db.RegisterFileDescriptor(DESCRIPTOR)\n\nCartItem = _reflection.GeneratedProtocolMessageType('CartItem', (_message.Message,), dict(\n  DESCRIPTOR = _CARTITEM,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CartItem)\n  ))\n_sym_db.RegisterMessage(CartItem)\n\nAddItemRequest = _reflection.GeneratedProtocolMessageType('AddItemRequest', (_message.Message,), dict(\n  DESCRIPTOR = _ADDITEMREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.AddItemRequest)\n  ))\n_sym_db.RegisterMessage(AddItemRequest)\n\nEmptyCartRequest = _reflection.GeneratedProtocolMessageType('EmptyCartRequest', (_message.Message,), dict(\n  DESCRIPTOR = _EMPTYCARTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.EmptyCartRequest)\n  ))\n_sym_db.RegisterMessage(EmptyCartRequest)\n\nGetCartRequest = _reflection.GeneratedProtocolMessageType('GetCartRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETCARTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetCartRequest)\n  ))\n_sym_db.RegisterMessage(GetCartRequest)\n\nCart = _reflection.GeneratedProtocolMessageType('Cart', (_message.Message,), dict(\n  DESCRIPTOR = _CART,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Cart)\n  ))\n_sym_db.RegisterMessage(Cart)\n\nEmpty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), dict(\n  DESCRIPTOR = _EMPTY,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Empty)\n  ))\n_sym_db.RegisterMessage(Empty)\n\nListRecommendationsRequest = _reflection.GeneratedProtocolMessageType('ListRecommendationsRequest', (_message.Message,), dict(\n  DESCRIPTOR = _LISTRECOMMENDATIONSREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsRequest)\n  ))\n_sym_db.RegisterMessage(ListRecommendationsRequest)\n\nListRecommendationsResponse = _reflection.GeneratedProtocolMessageType('ListRecommendationsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _LISTRECOMMENDATIONSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListRecommendationsResponse)\n  ))\n_sym_db.RegisterMessage(ListRecommendationsResponse)\n\nProduct = _reflection.GeneratedProtocolMessageType('Product', (_message.Message,), dict(\n  DESCRIPTOR = _PRODUCT,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Product)\n  ))\n_sym_db.RegisterMessage(Product)\n\nListProductsResponse = _reflection.GeneratedProtocolMessageType('ListProductsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _LISTPRODUCTSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ListProductsResponse)\n  ))\n_sym_db.RegisterMessage(ListProductsResponse)\n\nGetProductRequest = _reflection.GeneratedProtocolMessageType('GetProductRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETPRODUCTREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetProductRequest)\n  ))\n_sym_db.RegisterMessage(GetProductRequest)\n\nSearchProductsRequest = _reflection.GeneratedProtocolMessageType('SearchProductsRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SEARCHPRODUCTSREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsRequest)\n  ))\n_sym_db.RegisterMessage(SearchProductsRequest)\n\nSearchProductsResponse = _reflection.GeneratedProtocolMessageType('SearchProductsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _SEARCHPRODUCTSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SearchProductsResponse)\n  ))\n_sym_db.RegisterMessage(SearchProductsResponse)\n\nGetQuoteRequest = _reflection.GeneratedProtocolMessageType('GetQuoteRequest', (_message.Message,), dict(\n  DESCRIPTOR = _GETQUOTEREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteRequest)\n  ))\n_sym_db.RegisterMessage(GetQuoteRequest)\n\nGetQuoteResponse = _reflection.GeneratedProtocolMessageType('GetQuoteResponse', (_message.Message,), dict(\n  DESCRIPTOR = _GETQUOTERESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetQuoteResponse)\n  ))\n_sym_db.RegisterMessage(GetQuoteResponse)\n\nShipOrderRequest = _reflection.GeneratedProtocolMessageType('ShipOrderRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SHIPORDERREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderRequest)\n  ))\n_sym_db.RegisterMessage(ShipOrderRequest)\n\nShipOrderResponse = _reflection.GeneratedProtocolMessageType('ShipOrderResponse', (_message.Message,), dict(\n  DESCRIPTOR = _SHIPORDERRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ShipOrderResponse)\n  ))\n_sym_db.RegisterMessage(ShipOrderResponse)\n\nAddress = _reflection.GeneratedProtocolMessageType('Address', (_message.Message,), dict(\n  DESCRIPTOR = _ADDRESS,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Address)\n  ))\n_sym_db.RegisterMessage(Address)\n\nMoney = _reflection.GeneratedProtocolMessageType('Money', (_message.Message,), dict(\n  DESCRIPTOR = _MONEY,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Money)\n  ))\n_sym_db.RegisterMessage(Money)\n\nGetSupportedCurrenciesResponse = _reflection.GeneratedProtocolMessageType('GetSupportedCurrenciesResponse', (_message.Message,), dict(\n  DESCRIPTOR = _GETSUPPORTEDCURRENCIESRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.GetSupportedCurrenciesResponse)\n  ))\n_sym_db.RegisterMessage(GetSupportedCurrenciesResponse)\n\nCurrencyConversionRequest = _reflection.GeneratedProtocolMessageType('CurrencyConversionRequest', (_message.Message,), dict(\n  DESCRIPTOR = _CURRENCYCONVERSIONREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CurrencyConversionRequest)\n  ))\n_sym_db.RegisterMessage(CurrencyConversionRequest)\n\nCreditCardInfo = _reflection.GeneratedProtocolMessageType('CreditCardInfo', (_message.Message,), dict(\n  DESCRIPTOR = _CREDITCARDINFO,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.CreditCardInfo)\n  ))\n_sym_db.RegisterMessage(CreditCardInfo)\n\nChargeRequest = _reflection.GeneratedProtocolMessageType('ChargeRequest', (_message.Message,), dict(\n  DESCRIPTOR = _CHARGEREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ChargeRequest)\n  ))\n_sym_db.RegisterMessage(ChargeRequest)\n\nChargeResponse = _reflection.GeneratedProtocolMessageType('ChargeResponse', (_message.Message,), dict(\n  DESCRIPTOR = _CHARGERESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.ChargeResponse)\n  ))\n_sym_db.RegisterMessage(ChargeResponse)\n\nOrderItem = _reflection.GeneratedProtocolMessageType('OrderItem', (_message.Message,), dict(\n  DESCRIPTOR = _ORDERITEM,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.OrderItem)\n  ))\n_sym_db.RegisterMessage(OrderItem)\n\nOrderResult = _reflection.GeneratedProtocolMessageType('OrderResult', (_message.Message,), dict(\n  DESCRIPTOR = _ORDERRESULT,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.OrderResult)\n  ))\n_sym_db.RegisterMessage(OrderResult)\n\nSendOrderConfirmationRequest = _reflection.GeneratedProtocolMessageType('SendOrderConfirmationRequest', (_message.Message,), dict(\n  DESCRIPTOR = _SENDORDERCONFIRMATIONREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.SendOrderConfirmationRequest)\n  ))\n_sym_db.RegisterMessage(SendOrderConfirmationRequest)\n\nPlaceOrderRequest = _reflection.GeneratedProtocolMessageType('PlaceOrderRequest', (_message.Message,), dict(\n  DESCRIPTOR = _PLACEORDERREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderRequest)\n  ))\n_sym_db.RegisterMessage(PlaceOrderRequest)\n\nPlaceOrderResponse = _reflection.GeneratedProtocolMessageType('PlaceOrderResponse', (_message.Message,), dict(\n  DESCRIPTOR = _PLACEORDERRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.PlaceOrderResponse)\n  ))\n_sym_db.RegisterMessage(PlaceOrderResponse)\n\nAdsRequest = _reflection.GeneratedProtocolMessageType('AdsRequest', (_message.Message,), dict(\n  DESCRIPTOR = _ADSREQUEST,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.AdsRequest)\n  ))\n_sym_db.RegisterMessage(AdsRequest)\n\nAdsResponse = _reflection.GeneratedProtocolMessageType('AdsResponse', (_message.Message,), dict(\n  DESCRIPTOR = _ADSRESPONSE,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.AdsResponse)\n  ))\n_sym_db.RegisterMessage(AdsResponse)\n\nAd = _reflection.GeneratedProtocolMessageType('Ad', (_message.Message,), dict(\n  DESCRIPTOR = _AD,\n  __module__ = 'demo_pb2'\n  # @@protoc_insertion_point(class_scope:hipstershop.Ad)\n  ))\n_sym_db.RegisterMessage(Ad)\n\n\n\n_CARTSERVICE = _descriptor.ServiceDescriptor(\n  name='CartService',\n  full_name='hipstershop.CartService',\n  file=DESCRIPTOR,\n  index=0,\n  options=None,\n  serialized_start=2332,\n  serialized_end=2534,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='AddItem',\n    full_name='hipstershop.CartService.AddItem',\n    index=0,\n    containing_service=None,\n    input_type=_ADDITEMREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='GetCart',\n    full_name='hipstershop.CartService.GetCart',\n    index=1,\n    containing_service=None,\n    input_type=_GETCARTREQUEST,\n    output_type=_CART,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='EmptyCart',\n    full_name='hipstershop.CartService.EmptyCart',\n    index=2,\n    containing_service=None,\n    input_type=_EMPTYCARTREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CARTSERVICE)\n\nDESCRIPTOR.services_by_name['CartService'] = _CARTSERVICE\n\n\n_RECOMMENDATIONSERVICE = _descriptor.ServiceDescriptor(\n  name='RecommendationService',\n  full_name='hipstershop.RecommendationService',\n  file=DESCRIPTOR,\n  index=1,\n  options=None,\n  serialized_start=2537,\n  serialized_end=2668,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='ListRecommendations',\n    full_name='hipstershop.RecommendationService.ListRecommendations',\n    index=0,\n    containing_service=None,\n    input_type=_LISTRECOMMENDATIONSREQUEST,\n    output_type=_LISTRECOMMENDATIONSRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_RECOMMENDATIONSERVICE)\n\nDESCRIPTOR.services_by_name['RecommendationService'] = _RECOMMENDATIONSERVICE\n\n\n_PRODUCTCATALOGSERVICE = _descriptor.ServiceDescriptor(\n  name='ProductCatalogService',\n  full_name='hipstershop.ProductCatalogService',\n  file=DESCRIPTOR,\n  index=2,\n  options=None,\n  serialized_start=2671,\n  serialized_end=2930,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='ListProducts',\n    full_name='hipstershop.ProductCatalogService.ListProducts',\n    index=0,\n    containing_service=None,\n    input_type=_EMPTY,\n    output_type=_LISTPRODUCTSRESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='GetProduct',\n    full_name='hipstershop.ProductCatalogService.GetProduct',\n    index=1,\n    containing_service=None,\n    input_type=_GETPRODUCTREQUEST,\n    output_type=_PRODUCT,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='SearchProducts',\n    full_name='hipstershop.ProductCatalogService.SearchProducts',\n    index=2,\n    containing_service=None,\n    input_type=_SEARCHPRODUCTSREQUEST,\n    output_type=_SEARCHPRODUCTSRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_PRODUCTCATALOGSERVICE)\n\nDESCRIPTOR.services_by_name['ProductCatalogService'] = _PRODUCTCATALOGSERVICE\n\n\n_SHIPPINGSERVICE = _descriptor.ServiceDescriptor(\n  name='ShippingService',\n  full_name='hipstershop.ShippingService',\n  file=DESCRIPTOR,\n  index=3,\n  options=None,\n  serialized_start=2933,\n  serialized_end=3103,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='GetQuote',\n    full_name='hipstershop.ShippingService.GetQuote',\n    index=0,\n    containing_service=None,\n    input_type=_GETQUOTEREQUEST,\n    output_type=_GETQUOTERESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='ShipOrder',\n    full_name='hipstershop.ShippingService.ShipOrder',\n    index=1,\n    containing_service=None,\n    input_type=_SHIPORDERREQUEST,\n    output_type=_SHIPORDERRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_SHIPPINGSERVICE)\n\nDESCRIPTOR.services_by_name['ShippingService'] = _SHIPPINGSERVICE\n\n\n_CURRENCYSERVICE = _descriptor.ServiceDescriptor(\n  name='CurrencyService',\n  full_name='hipstershop.CurrencyService',\n  file=DESCRIPTOR,\n  index=4,\n  options=None,\n  serialized_start=3106,\n  serialized_end=3289,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='GetSupportedCurrencies',\n    full_name='hipstershop.CurrencyService.GetSupportedCurrencies',\n    index=0,\n    containing_service=None,\n    input_type=_EMPTY,\n    output_type=_GETSUPPORTEDCURRENCIESRESPONSE,\n    options=None,\n  ),\n  _descriptor.MethodDescriptor(\n    name='Convert',\n    full_name='hipstershop.CurrencyService.Convert',\n    index=1,\n    containing_service=None,\n    input_type=_CURRENCYCONVERSIONREQUEST,\n    output_type=_MONEY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CURRENCYSERVICE)\n\nDESCRIPTOR.services_by_name['CurrencyService'] = _CURRENCYSERVICE\n\n\n_PAYMENTSERVICE = _descriptor.ServiceDescriptor(\n  name='PaymentService',\n  full_name='hipstershop.PaymentService',\n  file=DESCRIPTOR,\n  index=5,\n  options=None,\n  serialized_start=3291,\n  serialized_end=3376,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='Charge',\n    full_name='hipstershop.PaymentService.Charge',\n    index=0,\n    containing_service=None,\n    input_type=_CHARGEREQUEST,\n    output_type=_CHARGERESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_PAYMENTSERVICE)\n\nDESCRIPTOR.services_by_name['PaymentService'] = _PAYMENTSERVICE\n\n\n_EMAILSERVICE = _descriptor.ServiceDescriptor(\n  name='EmailService',\n  full_name='hipstershop.EmailService',\n  file=DESCRIPTOR,\n  index=6,\n  options=None,\n  serialized_start=3378,\n  serialized_end=3482,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='SendOrderConfirmation',\n    full_name='hipstershop.EmailService.SendOrderConfirmation',\n    index=0,\n    containing_service=None,\n    input_type=_SENDORDERCONFIRMATIONREQUEST,\n    output_type=_EMPTY,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_EMAILSERVICE)\n\nDESCRIPTOR.services_by_name['EmailService'] = _EMAILSERVICE\n\n\n_CHECKOUTSERVICE = _descriptor.ServiceDescriptor(\n  name='CheckoutService',\n  full_name='hipstershop.CheckoutService',\n  file=DESCRIPTOR,\n  index=7,\n  options=None,\n  serialized_start=3484,\n  serialized_end=3582,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='PlaceOrder',\n    full_name='hipstershop.CheckoutService.PlaceOrder',\n    index=0,\n    containing_service=None,\n    input_type=_PLACEORDERREQUEST,\n    output_type=_PLACEORDERRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_CHECKOUTSERVICE)\n\nDESCRIPTOR.services_by_name['CheckoutService'] = _CHECKOUTSERVICE\n\n\n_ADSSERVICE = _descriptor.ServiceDescriptor(\n  name='AdsService',\n  full_name='hipstershop.AdsService',\n  file=DESCRIPTOR,\n  index=8,\n  options=None,\n  serialized_start=3584,\n  serialized_end=3659,\n  methods=[\n  _descriptor.MethodDescriptor(\n    name='GetAds',\n    full_name='hipstershop.AdsService.GetAds',\n    index=0,\n    containing_service=None,\n    input_type=_ADSREQUEST,\n    output_type=_ADSRESPONSE,\n    options=None,\n  ),\n])\n_sym_db.RegisterServiceDescriptor(_ADSSERVICE)\n\nDESCRIPTOR.services_by_name['AdsService'] = _ADSSERVICE\n\n# @@protoc_insertion_point(module_scope)\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/demo_pb2_grpc.py",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!\nimport grpc\n\nimport demo_pb2 as demo__pb2\n\n\nclass CartServiceStub(object):\n  \"\"\"-----------------Cart service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.AddItem = channel.unary_unary(\n        '/hipstershop.CartService/AddItem',\n        request_serializer=demo__pb2.AddItemRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n    self.GetCart = channel.unary_unary(\n        '/hipstershop.CartService/GetCart',\n        request_serializer=demo__pb2.GetCartRequest.SerializeToString,\n        response_deserializer=demo__pb2.Cart.FromString,\n        )\n    self.EmptyCart = channel.unary_unary(\n        '/hipstershop.CartService/EmptyCart',\n        request_serializer=demo__pb2.EmptyCartRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n\n\nclass CartServiceServicer(object):\n  \"\"\"-----------------Cart service-----------------\n\n  \"\"\"\n\n  def AddItem(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def GetCart(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def EmptyCart(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CartServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'AddItem': grpc.unary_unary_rpc_method_handler(\n          servicer.AddItem,\n          request_deserializer=demo__pb2.AddItemRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n      'GetCart': grpc.unary_unary_rpc_method_handler(\n          servicer.GetCart,\n          request_deserializer=demo__pb2.GetCartRequest.FromString,\n          response_serializer=demo__pb2.Cart.SerializeToString,\n      ),\n      'EmptyCart': grpc.unary_unary_rpc_method_handler(\n          servicer.EmptyCart,\n          request_deserializer=demo__pb2.EmptyCartRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CartService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass RecommendationServiceStub(object):\n  \"\"\"---------------Recommendation service----------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.ListRecommendations = channel.unary_unary(\n        '/hipstershop.RecommendationService/ListRecommendations',\n        request_serializer=demo__pb2.ListRecommendationsRequest.SerializeToString,\n        response_deserializer=demo__pb2.ListRecommendationsResponse.FromString,\n        )\n\n\nclass RecommendationServiceServicer(object):\n  \"\"\"---------------Recommendation service----------\n\n  \"\"\"\n\n  def ListRecommendations(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_RecommendationServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'ListRecommendations': grpc.unary_unary_rpc_method_handler(\n          servicer.ListRecommendations,\n          request_deserializer=demo__pb2.ListRecommendationsRequest.FromString,\n          response_serializer=demo__pb2.ListRecommendationsResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.RecommendationService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass ProductCatalogServiceStub(object):\n  \"\"\"---------------Product Catalog----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.ListProducts = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/ListProducts',\n        request_serializer=demo__pb2.Empty.SerializeToString,\n        response_deserializer=demo__pb2.ListProductsResponse.FromString,\n        )\n    self.GetProduct = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/GetProduct',\n        request_serializer=demo__pb2.GetProductRequest.SerializeToString,\n        response_deserializer=demo__pb2.Product.FromString,\n        )\n    self.SearchProducts = channel.unary_unary(\n        '/hipstershop.ProductCatalogService/SearchProducts',\n        request_serializer=demo__pb2.SearchProductsRequest.SerializeToString,\n        response_deserializer=demo__pb2.SearchProductsResponse.FromString,\n        )\n\n\nclass ProductCatalogServiceServicer(object):\n  \"\"\"---------------Product Catalog----------------\n\n  \"\"\"\n\n  def ListProducts(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def GetProduct(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def SearchProducts(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_ProductCatalogServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'ListProducts': grpc.unary_unary_rpc_method_handler(\n          servicer.ListProducts,\n          request_deserializer=demo__pb2.Empty.FromString,\n          response_serializer=demo__pb2.ListProductsResponse.SerializeToString,\n      ),\n      'GetProduct': grpc.unary_unary_rpc_method_handler(\n          servicer.GetProduct,\n          request_deserializer=demo__pb2.GetProductRequest.FromString,\n          response_serializer=demo__pb2.Product.SerializeToString,\n      ),\n      'SearchProducts': grpc.unary_unary_rpc_method_handler(\n          servicer.SearchProducts,\n          request_deserializer=demo__pb2.SearchProductsRequest.FromString,\n          response_serializer=demo__pb2.SearchProductsResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.ProductCatalogService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass ShippingServiceStub(object):\n  \"\"\"---------------Shipping Service----------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.GetQuote = channel.unary_unary(\n        '/hipstershop.ShippingService/GetQuote',\n        request_serializer=demo__pb2.GetQuoteRequest.SerializeToString,\n        response_deserializer=demo__pb2.GetQuoteResponse.FromString,\n        )\n    self.ShipOrder = channel.unary_unary(\n        '/hipstershop.ShippingService/ShipOrder',\n        request_serializer=demo__pb2.ShipOrderRequest.SerializeToString,\n        response_deserializer=demo__pb2.ShipOrderResponse.FromString,\n        )\n\n\nclass ShippingServiceServicer(object):\n  \"\"\"---------------Shipping Service----------\n\n  \"\"\"\n\n  def GetQuote(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def ShipOrder(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_ShippingServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'GetQuote': grpc.unary_unary_rpc_method_handler(\n          servicer.GetQuote,\n          request_deserializer=demo__pb2.GetQuoteRequest.FromString,\n          response_serializer=demo__pb2.GetQuoteResponse.SerializeToString,\n      ),\n      'ShipOrder': grpc.unary_unary_rpc_method_handler(\n          servicer.ShipOrder,\n          request_deserializer=demo__pb2.ShipOrderRequest.FromString,\n          response_serializer=demo__pb2.ShipOrderResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.ShippingService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass CurrencyServiceStub(object):\n  \"\"\"-----------------Currency service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.GetSupportedCurrencies = channel.unary_unary(\n        '/hipstershop.CurrencyService/GetSupportedCurrencies',\n        request_serializer=demo__pb2.Empty.SerializeToString,\n        response_deserializer=demo__pb2.GetSupportedCurrenciesResponse.FromString,\n        )\n    self.Convert = channel.unary_unary(\n        '/hipstershop.CurrencyService/Convert',\n        request_serializer=demo__pb2.CurrencyConversionRequest.SerializeToString,\n        response_deserializer=demo__pb2.Money.FromString,\n        )\n\n\nclass CurrencyServiceServicer(object):\n  \"\"\"-----------------Currency service-----------------\n\n  \"\"\"\n\n  def GetSupportedCurrencies(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n  def Convert(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CurrencyServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'GetSupportedCurrencies': grpc.unary_unary_rpc_method_handler(\n          servicer.GetSupportedCurrencies,\n          request_deserializer=demo__pb2.Empty.FromString,\n          response_serializer=demo__pb2.GetSupportedCurrenciesResponse.SerializeToString,\n      ),\n      'Convert': grpc.unary_unary_rpc_method_handler(\n          servicer.Convert,\n          request_deserializer=demo__pb2.CurrencyConversionRequest.FromString,\n          response_serializer=demo__pb2.Money.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CurrencyService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass PaymentServiceStub(object):\n  \"\"\"-------------Payment service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.Charge = channel.unary_unary(\n        '/hipstershop.PaymentService/Charge',\n        request_serializer=demo__pb2.ChargeRequest.SerializeToString,\n        response_deserializer=demo__pb2.ChargeResponse.FromString,\n        )\n\n\nclass PaymentServiceServicer(object):\n  \"\"\"-------------Payment service-----------------\n\n  \"\"\"\n\n  def Charge(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_PaymentServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'Charge': grpc.unary_unary_rpc_method_handler(\n          servicer.Charge,\n          request_deserializer=demo__pb2.ChargeRequest.FromString,\n          response_serializer=demo__pb2.ChargeResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.PaymentService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass EmailServiceStub(object):\n  \"\"\"-------------Email service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.SendOrderConfirmation = channel.unary_unary(\n        '/hipstershop.EmailService/SendOrderConfirmation',\n        request_serializer=demo__pb2.SendOrderConfirmationRequest.SerializeToString,\n        response_deserializer=demo__pb2.Empty.FromString,\n        )\n\n\nclass EmailServiceServicer(object):\n  \"\"\"-------------Email service-----------------\n\n  \"\"\"\n\n  def SendOrderConfirmation(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_EmailServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'SendOrderConfirmation': grpc.unary_unary_rpc_method_handler(\n          servicer.SendOrderConfirmation,\n          request_deserializer=demo__pb2.SendOrderConfirmationRequest.FromString,\n          response_serializer=demo__pb2.Empty.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.EmailService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass CheckoutServiceStub(object):\n  \"\"\"-------------Checkout service-----------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.PlaceOrder = channel.unary_unary(\n        '/hipstershop.CheckoutService/PlaceOrder',\n        request_serializer=demo__pb2.PlaceOrderRequest.SerializeToString,\n        response_deserializer=demo__pb2.PlaceOrderResponse.FromString,\n        )\n\n\nclass CheckoutServiceServicer(object):\n  \"\"\"-------------Checkout service-----------------\n\n  \"\"\"\n\n  def PlaceOrder(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_CheckoutServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'PlaceOrder': grpc.unary_unary_rpc_method_handler(\n          servicer.PlaceOrder,\n          request_deserializer=demo__pb2.PlaceOrderRequest.FromString,\n          response_serializer=demo__pb2.PlaceOrderResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.CheckoutService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n\n\nclass AdsServiceStub(object):\n  \"\"\"------------Ads service------------------\n\n  \"\"\"\n\n  def __init__(self, channel):\n    \"\"\"Constructor.\n\n    Args:\n      channel: A grpc.Channel.\n    \"\"\"\n    self.GetAds = channel.unary_unary(\n        '/hipstershop.AdsService/GetAds',\n        request_serializer=demo__pb2.AdsRequest.SerializeToString,\n        response_deserializer=demo__pb2.AdsResponse.FromString,\n        )\n\n\nclass AdsServiceServicer(object):\n  \"\"\"------------Ads service------------------\n\n  \"\"\"\n\n  def GetAds(self, request, context):\n    # missing associated documentation comment in .proto file\n    pass\n    context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n    context.set_details('Method not implemented!')\n    raise NotImplementedError('Method not implemented!')\n\n\ndef add_AdsServiceServicer_to_server(servicer, server):\n  rpc_method_handlers = {\n      'GetAds': grpc.unary_unary_rpc_method_handler(\n          servicer.GetAds,\n          request_deserializer=demo__pb2.AdsRequest.FromString,\n          response_serializer=demo__pb2.AdsResponse.SerializeToString,\n      ),\n  }\n  generic_handler = grpc.method_handlers_generic_handler(\n      'hipstershop.AdsService', rpc_method_handlers)\n  server.add_generic_rpc_handlers((generic_handler,))\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_recommendationservice_genproto]\n\n# script to compile python protos\n#\n# requires gRPC tools:\n#   pip install -r requirements.txt\n\npython -m grpc_tools.protoc -I../../pb --python_out=. --grpc_python_out=. ../../pb/demo.proto\n\n# [END gke_recommendationservice_genproto]"
  },
  {
    "path": "microservices-demo/src/recommendationservice/logger.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport logging\nimport sys\nfrom pythonjsonlogger import jsonlogger\n\n# TODO(yoshifumi) this class is duplicated since other Python services are\n# not sharing the modules for logging.\nclass CustomJsonFormatter(jsonlogger.JsonFormatter):\n  def add_fields(self, log_record, record, message_dict):\n    super(CustomJsonFormatter, self).add_fields(log_record, record, message_dict)\n    if not log_record.get('timestamp'):\n      log_record['timestamp'] = record.created\n    if log_record.get('severity'):\n      log_record['severity'] = log_record['severity'].upper()\n    else:\n      log_record['severity'] = record.levelname\n\ndef getJSONLogger(name):\n  logger = logging.getLogger(name)\n  handler = logging.StreamHandler(sys.stdout)\n  formatter = CustomJsonFormatter('(timestamp) (severity) (name) (message)')\n  handler.setFormatter(formatter)\n  logger.addHandler(handler)\n  logger.setLevel(logging.INFO)\n  logger.propagate = False\n  return logger\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/pytest.ini",
    "content": "[pytest]\ntestpaths = tests\nconsole_output_style = classic\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/recommendation_server.py",
    "content": "#!/usr/bin/python\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport os\nimport random\nimport time\nimport traceback\nfrom concurrent import futures\n\nimport googleclouddebugger\nimport googlecloudprofiler\nfrom google.auth.exceptions import DefaultCredentialsError\nimport grpc\nfrom opencensus.ext.stackdriver import trace_exporter as stackdriver_exporter\nfrom opencensus.ext.grpc import server_interceptor\nfrom opencensus.trace import samplers\nfrom opencensus.common.transports.async_ import AsyncTransport\n\nimport demo_pb2\nimport demo_pb2_grpc\nfrom grpc_health.v1 import health_pb2\nfrom grpc_health.v1 import health_pb2_grpc\n\nfrom logger import getJSONLogger\nlogger = getJSONLogger('recommendationservice-server')\n\ndef initStackdriverProfiling():\n  project_id = None\n  try:\n    project_id = os.environ[\"GCP_PROJECT_ID\"]\n  except KeyError:\n    # Environment variable not set\n    pass\n\n  for retry in range(1,4):\n    try:\n      if project_id:\n        googlecloudprofiler.start(service='recommendation_server', service_version='1.0.0', verbose=0, project_id=project_id)\n      else:\n        googlecloudprofiler.start(service='recommendation_server', service_version='1.0.0', verbose=0)\n      logger.info(\"Successfully started Stackdriver Profiler.\")\n      return\n    except (BaseException) as exc:\n      logger.info(\"Unable to start Stackdriver Profiler Python agent. \" + str(exc))\n      if (retry < 4):\n        logger.info(\"Sleeping %d seconds to retry Stackdriver Profiler agent initialization\"%(retry*10))\n        time.sleep (1)\n      else:\n        logger.warning(\"Could not initialize Stackdriver Profiler after retrying, giving up\")\n  return\n\nclass RecommendationService(demo_pb2_grpc.RecommendationServiceServicer):\n    def ListRecommendations(self, request, context):\n        max_responses = 5\n        # fetch list of products from product catalog stub\n        cat_response = product_catalog_stub.ListProducts(demo_pb2.Empty())\n        product_ids = [x.id for x in cat_response.products]\n        filtered_products = list(set(product_ids)-set(request.product_ids))\n        num_products = len(filtered_products)\n        num_return = min(max_responses, num_products)\n        # sample list of indicies to return\n        indices = random.sample(range(num_products), num_return)\n        # fetch product ids from indices\n        prod_list = [filtered_products[i] for i in indices]\n        logger.info(\"[Recv ListRecommendations] product_ids={}\".format(prod_list))\n        # build and return response\n        response = demo_pb2.ListRecommendationsResponse()\n        response.product_ids.extend(prod_list)\n        return response\n\n    def Check(self, request, context):\n        return health_pb2.HealthCheckResponse(\n            status=health_pb2.HealthCheckResponse.SERVING)\n\n    def Watch(self, request, context):\n        return health_pb2.HealthCheckResponse(\n            status=health_pb2.HealthCheckResponse.UNIMPLEMENTED)\n\n\nif __name__ == \"__main__\":\n    logger.info(\"initializing recommendationservice\")\n\n    try:\n      if \"DISABLE_PROFILER\" in os.environ:\n        raise KeyError()\n      else:\n        logger.info(\"Profiler enabled.\")\n        initStackdriverProfiling()\n    except KeyError:\n        logger.info(\"Profiler disabled.\")\n\n    try:\n      if \"DISABLE_TRACING\" in os.environ:\n        raise KeyError()\n      else:\n        logger.info(\"Tracing enabled.\")\n        sampler = samplers.AlwaysOnSampler()\n        exporter = stackdriver_exporter.StackdriverExporter(\n          project_id=os.environ.get('GCP_PROJECT_ID'),\n          transport=AsyncTransport)\n        tracer_interceptor = server_interceptor.OpenCensusServerInterceptor(sampler, exporter)\n    except (KeyError, DefaultCredentialsError):\n        logger.info(\"Tracing disabled.\")\n        tracer_interceptor = server_interceptor.OpenCensusServerInterceptor()\n    except Exception as e:\n        logger.warn(f\"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled.\") \n        tracer_interceptor = server_interceptor.OpenCensusServerInterceptor()\n   \n    try:\n      if \"DISABLE_DEBUGGER\" in os.environ:\n        raise KeyError()\n      else:\n        logger.info(\"Debugger enabled.\")\n        try:\n          googleclouddebugger.enable(\n              module='recommendationserver',\n              version='1.0.0'\n          )\n        except (Exception, DefaultCredentialsError):\n            logger.error(\"Could not enable debugger\")\n            logger.error(traceback.print_exc())\n            pass\n    except (Exception, DefaultCredentialsError):\n        logger.info(\"Debugger disabled.\")\n\n    port = os.environ.get('PORT', \"8080\")\n    catalog_addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR', '')\n    if catalog_addr == \"\":\n        raise Exception('PRODUCT_CATALOG_SERVICE_ADDR environment variable not set')\n    logger.info(\"product catalog address: \" + catalog_addr)\n    channel = grpc.insecure_channel(catalog_addr)\n    product_catalog_stub = demo_pb2_grpc.ProductCatalogServiceStub(channel)\n\n    # create gRPC server\n    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),\n                      interceptors=(tracer_interceptor,))\n\n    # add class to gRPC server\n    service = RecommendationService()\n    demo_pb2_grpc.add_RecommendationServiceServicer_to_server(service, server)\n    health_pb2_grpc.add_HealthServicer_to_server(service, server)\n\n    # start server\n    logger.info(\"listening on port: \" + port)\n    server.add_insecure_port('[::]:'+port)\n    server.start()\n\n    # keep alive\n    try:\n         while True:\n            time.sleep(10000)\n    except KeyboardInterrupt:\n            server.stop(0)\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/requirements.in",
    "content": "google-api-core==2.8.2\ngoogle-python-cloud-debugger==3.1\ngoogle-cloud-profiler==4.0.0\ngrpcio-health-checking==1.47.0\ngrpcio==1.47.0\nopencensus==0.9.0\nopencensus-ext-stackdriver==0.8.0\nopencensus-ext-grpc==0.7.2\npython-json-logger==2.0.4\nrequests==2.28.1\nrsa==4.8\npyyaml==6.0\nprotobuf==3.20.1 # transitive dependency, move when google-api is bumped safely\npytest==7.1.3\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/requirements.txt",
    "content": "#\n# This file is autogenerated by pip-compile with python 3.7\n# To update, run:\n#\n#    pip-compile --output-file=requirements.txt requirements.in\n#\nattrs==22.1.0\n    # via pytest\ncachecontrol==0.12.11\n    # via firebase-admin\ncachetools==5.2.0\n    # via google-auth\ncertifi==2022.6.15\n    # via requests\ncharset-normalizer==2.1.1\n    # via requests\nfirebase-admin==5.2.0\n    # via google-python-cloud-debugger\ngoogle-api-core[grpc]==2.8.2\n    # via\n    #   -r requirements.in\n    #   firebase-admin\n    #   google-api-python-client\n    #   google-cloud-core\n    #   google-cloud-firestore\n    #   google-cloud-monitoring\n    #   google-cloud-storage\n    #   google-cloud-trace\n    #   google-python-cloud-debugger\n    #   opencensus\ngoogle-api-python-client==2.58.0\n    # via\n    #   firebase-admin\n    #   google-cloud-profiler\n    #   google-python-cloud-debugger\ngoogle-auth==2.11.0\n    # via\n    #   google-api-core\n    #   google-api-python-client\n    #   google-auth-httplib2\n    #   google-cloud-core\n    #   google-cloud-profiler\n    #   google-cloud-storage\n    #   google-python-cloud-debugger\ngoogle-auth-httplib2==0.1.0\n    # via\n    #   google-api-python-client\n    #   google-cloud-profiler\n    #   google-python-cloud-debugger\ngoogle-cloud-core==2.3.2\n    # via\n    #   google-cloud-firestore\n    #   google-cloud-storage\n    #   google-cloud-trace\ngoogle-cloud-firestore==2.6.1\n    # via firebase-admin\ngoogle-cloud-monitoring==2.11.1\n    # via opencensus-ext-stackdriver\ngoogle-cloud-profiler==4.0.0\n    # via -r requirements.in\ngoogle-cloud-storage==2.5.0\n    # via firebase-admin\ngoogle-cloud-trace==0.24.2\n    # via opencensus-ext-stackdriver\ngoogle-crc32c==1.3.0\n    # via google-resumable-media\ngoogle-python-cloud-debugger==3.1\n    # via -r requirements.in\ngoogle-resumable-media==2.3.3\n    # via google-cloud-storage\ngoogleapis-common-protos==1.56.4\n    # via\n    #   google-api-core\n    #   grpcio-status\ngrpcio==1.47.0\n    # via\n    #   -r requirements.in\n    #   google-api-core\n    #   grpcio-health-checking\n    #   grpcio-status\n    #   opencensus-ext-grpc\ngrpcio-health-checking==1.47.0\n    # via -r requirements.in\ngrpcio-status==1.47.0\n    # via google-api-core\nhttplib2==0.20.4\n    # via\n    #   google-api-python-client\n    #   google-auth-httplib2\nidna==2.10\n    # via requests\niniconfig==1.1.1\n    # via pytest\nmsgpack==1.0.4\n    # via cachecontrol\nopencensus==0.9.0\n    # via\n    #   -r requirements.in\n    #   opencensus-ext-grpc\n    #   opencensus-ext-stackdriver\nopencensus-context==0.1.3\n    # via opencensus\nopencensus-ext-grpc==0.7.2\n    # via -r requirements.in\nopencensus-ext-stackdriver==0.8.0\n    # via -r requirements.in\npackaging==21.3\n    # via pytest\npluggy==1.0.0\n    # via pytest\nproto-plus==1.22.1\n    # via\n    #   google-cloud-firestore\n    #   google-cloud-monitoring\nprotobuf==3.20.1\n    # via\n    #   -r requirements.in\n    #   google-api-core\n    #   google-cloud-firestore\n    #   google-cloud-monitoring\n    #   google-cloud-profiler\n    #   google-cloud-trace\n    #   googleapis-common-protos\n    #   grpcio-health-checking\n    #   grpcio-status\n    #   proto-plus\npy==1.11.0\n    # via pytest\npyasn1==0.4.8\n    # via\n    #   pyasn1-modules\n    #   rsa\npyasn1-modules==0.2.8\n    # via google-auth\npyparsing==2.4.7\n    # via httplib2\npytest==7.1.3\n    # via -r requirements.in\npython-json-logger==2.0.4\n    # via -r requirements.in\npyyaml==6.0\n    # via\n    #   -r requirements.in\n    #   google-python-cloud-debugger\nrequests==2.28.1\n    # via\n    #   -r requirements.in\n    #   cachecontrol\n    #   google-api-core\n    #   google-cloud-profiler\n    #   google-cloud-storage\nrsa==4.8\n    # via\n    #   -r requirements.in\n    #   google-auth\nsix==1.16.0\n    # via\n    #   google-auth\n    #   google-auth-httplib2\n    #   grpcio\ntomli==2.0.1\n    # via pytest\nuritemplate==3.0.1\n    # via google-api-python-client\nurllib3==1.26.12\n    # via requests\n"
  },
  {
    "path": "microservices-demo/src/recommendationservice/tests/test_sample.py",
    "content": "def func(x):\n    return x + 1\n\n\ndef test_answer():\n    assert func(3) == 4\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/.dockerignore",
    "content": "vendor/\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/Dockerfile",
    "content": "# Copyright 2020 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nFROM golang:1.18.4-alpine as builder\nRUN apk add --no-cache ca-certificates git\nRUN apk add build-base\nWORKDIR /src\n\n# restore dependencies\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\n\n# Skaffold passes in debug-oriented compiler flags\nARG SKAFFOLD_GO_GCFLAGS\nRUN go build -gcflags=\"${SKAFFOLD_GO_GCFLAGS}\" -o /go/bin/shippingservice .\n\nFROM alpine as release\nRUN apk add --no-cache ca-certificates\nRUN GRPC_HEALTH_PROBE_VERSION=v0.4.11 && \\\n    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \\\n    chmod +x /bin/grpc_health_probe\nWORKDIR /src\nCOPY --from=builder /go/bin/shippingservice /src/shippingservice\nENV APP_PORT=50051\n\n# Definition of this variable is used by 'skaffold debug' to identify a golang binary.\n# Default behavior - a failure prints a stack trace for the current goroutine.\n# See https://golang.org/pkg/runtime/\nENV GOTRACEBACK=single\n\nEXPOSE 50051\nENTRYPOINT [\"/src/shippingservice\"]\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/README.md",
    "content": "# Shipping Service\n\nThe Shipping service provides price quote, tracking IDs, and the impression of order fulfillment & shipping processes.\n\n## Local\n\nRun the following command to restore dependencies to `vendor/` directory:\n\n    dep ensure --vendor-only\n\n## Build\n\nFrom `src/shippingservice`, run:\n\n```\ndocker build ./\n```\n\n## Test\n\n```\ngo test .\n```\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/genproto/demo.pb.go",
    "content": "// Copyright 2020 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: demo.proto\n\npackage hipstershop\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.com/golang/protobuf/proto\"\n\tmath \"math\"\n)\n\nimport (\n\tcontext \"golang.org/x/net/context\"\n\tgrpc \"google.golang.org/grpc\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package\n\ntype CartItem struct {\n\tProductId            string   `protobuf:\"bytes,1,opt,name=product_id,json=productId,proto3\" json:\"product_id,omitempty\"`\n\tQuantity             int32    `protobuf:\"varint,2,opt,name=quantity,proto3\" json:\"quantity,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CartItem) Reset()         { *m = CartItem{} }\nfunc (m *CartItem) String() string { return proto.CompactTextString(m) }\nfunc (*CartItem) ProtoMessage()    {}\nfunc (*CartItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{0}\n}\n\nfunc (m *CartItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CartItem.Unmarshal(m, b)\n}\nfunc (m *CartItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CartItem.Marshal(b, m, deterministic)\n}\nfunc (m *CartItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CartItem.Merge(m, src)\n}\nfunc (m *CartItem) XXX_Size() int {\n\treturn xxx_messageInfo_CartItem.Size(m)\n}\nfunc (m *CartItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_CartItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CartItem proto.InternalMessageInfo\n\nfunc (m *CartItem) GetProductId() string {\n\tif m != nil {\n\t\treturn m.ProductId\n\t}\n\treturn \"\"\n}\n\nfunc (m *CartItem) GetQuantity() int32 {\n\tif m != nil {\n\t\treturn m.Quantity\n\t}\n\treturn 0\n}\n\ntype AddItemRequest struct {\n\tUserId               string    `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItem                 *CartItem `protobuf:\"bytes,2,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *AddItemRequest) Reset()         { *m = AddItemRequest{} }\nfunc (m *AddItemRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AddItemRequest) ProtoMessage()    {}\nfunc (*AddItemRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{1}\n}\n\nfunc (m *AddItemRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AddItemRequest.Unmarshal(m, b)\n}\nfunc (m *AddItemRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AddItemRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AddItemRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AddItemRequest.Merge(m, src)\n}\nfunc (m *AddItemRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AddItemRequest.Size(m)\n}\nfunc (m *AddItemRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AddItemRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AddItemRequest proto.InternalMessageInfo\n\nfunc (m *AddItemRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *AddItemRequest) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\ntype EmptyCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *EmptyCartRequest) Reset()         { *m = EmptyCartRequest{} }\nfunc (m *EmptyCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*EmptyCartRequest) ProtoMessage()    {}\nfunc (*EmptyCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{2}\n}\n\nfunc (m *EmptyCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_EmptyCartRequest.Unmarshal(m, b)\n}\nfunc (m *EmptyCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_EmptyCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *EmptyCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_EmptyCartRequest.Merge(m, src)\n}\nfunc (m *EmptyCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_EmptyCartRequest.Size(m)\n}\nfunc (m *EmptyCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_EmptyCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_EmptyCartRequest proto.InternalMessageInfo\n\nfunc (m *EmptyCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype GetCartRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetCartRequest) Reset()         { *m = GetCartRequest{} }\nfunc (m *GetCartRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetCartRequest) ProtoMessage()    {}\nfunc (*GetCartRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{3}\n}\n\nfunc (m *GetCartRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetCartRequest.Unmarshal(m, b)\n}\nfunc (m *GetCartRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetCartRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetCartRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetCartRequest.Merge(m, src)\n}\nfunc (m *GetCartRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetCartRequest.Size(m)\n}\nfunc (m *GetCartRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetCartRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetCartRequest proto.InternalMessageInfo\n\nfunc (m *GetCartRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\ntype Cart struct {\n\tUserId               string      `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *Cart) Reset()         { *m = Cart{} }\nfunc (m *Cart) String() string { return proto.CompactTextString(m) }\nfunc (*Cart) ProtoMessage()    {}\nfunc (*Cart) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{4}\n}\n\nfunc (m *Cart) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Cart.Unmarshal(m, b)\n}\nfunc (m *Cart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Cart.Marshal(b, m, deterministic)\n}\nfunc (m *Cart) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Cart.Merge(m, src)\n}\nfunc (m *Cart) XXX_Size() int {\n\treturn xxx_messageInfo_Cart.Size(m)\n}\nfunc (m *Cart) XXX_DiscardUnknown() {\n\txxx_messageInfo_Cart.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Cart proto.InternalMessageInfo\n\nfunc (m *Cart) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *Cart) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype Empty struct {\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Empty) Reset()         { *m = Empty{} }\nfunc (m *Empty) String() string { return proto.CompactTextString(m) }\nfunc (*Empty) ProtoMessage()    {}\nfunc (*Empty) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{5}\n}\n\nfunc (m *Empty) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Empty.Unmarshal(m, b)\n}\nfunc (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Empty.Marshal(b, m, deterministic)\n}\nfunc (m *Empty) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Empty.Merge(m, src)\n}\nfunc (m *Empty) XXX_Size() int {\n\treturn xxx_messageInfo_Empty.Size(m)\n}\nfunc (m *Empty) XXX_DiscardUnknown() {\n\txxx_messageInfo_Empty.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Empty proto.InternalMessageInfo\n\ntype ListRecommendationsRequest struct {\n\tUserId               string   `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tProductIds           []string `protobuf:\"bytes,2,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsRequest) Reset()         { *m = ListRecommendationsRequest{} }\nfunc (m *ListRecommendationsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsRequest) ProtoMessage()    {}\nfunc (*ListRecommendationsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{6}\n}\n\nfunc (m *ListRecommendationsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsRequest.Merge(m, src)\n}\nfunc (m *ListRecommendationsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsRequest.Size(m)\n}\nfunc (m *ListRecommendationsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsRequest proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *ListRecommendationsRequest) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype ListRecommendationsResponse struct {\n\tProductIds           []string `protobuf:\"bytes,1,rep,name=product_ids,json=productIds,proto3\" json:\"product_ids,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ListRecommendationsResponse) Reset()         { *m = ListRecommendationsResponse{} }\nfunc (m *ListRecommendationsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListRecommendationsResponse) ProtoMessage()    {}\nfunc (*ListRecommendationsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{7}\n}\n\nfunc (m *ListRecommendationsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Unmarshal(m, b)\n}\nfunc (m *ListRecommendationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListRecommendationsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListRecommendationsResponse.Merge(m, src)\n}\nfunc (m *ListRecommendationsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListRecommendationsResponse.Size(m)\n}\nfunc (m *ListRecommendationsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListRecommendationsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListRecommendationsResponse proto.InternalMessageInfo\n\nfunc (m *ListRecommendationsResponse) GetProductIds() []string {\n\tif m != nil {\n\t\treturn m.ProductIds\n\t}\n\treturn nil\n}\n\ntype Product struct {\n\tId          string `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tName        string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tPicture     string `protobuf:\"bytes,4,opt,name=picture,proto3\" json:\"picture,omitempty\"`\n\tPriceUsd    *Money `protobuf:\"bytes,5,opt,name=price_usd,json=priceUsd,proto3\" json:\"price_usd,omitempty\"`\n\t// Categories such as \"clothing\" or \"kitchen\" that can be used to look up\n\t// other related products.\n\tCategories           []string `protobuf:\"bytes,6,rep,name=categories,proto3\" json:\"categories,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Product) Reset()         { *m = Product{} }\nfunc (m *Product) String() string { return proto.CompactTextString(m) }\nfunc (*Product) ProtoMessage()    {}\nfunc (*Product) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{8}\n}\n\nfunc (m *Product) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Product.Unmarshal(m, b)\n}\nfunc (m *Product) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Product.Marshal(b, m, deterministic)\n}\nfunc (m *Product) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Product.Merge(m, src)\n}\nfunc (m *Product) XXX_Size() int {\n\treturn xxx_messageInfo_Product.Size(m)\n}\nfunc (m *Product) XXX_DiscardUnknown() {\n\txxx_messageInfo_Product.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Product proto.InternalMessageInfo\n\nfunc (m *Product) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetDescription() string {\n\tif m != nil {\n\t\treturn m.Description\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPicture() string {\n\tif m != nil {\n\t\treturn m.Picture\n\t}\n\treturn \"\"\n}\n\nfunc (m *Product) GetPriceUsd() *Money {\n\tif m != nil {\n\t\treturn m.PriceUsd\n\t}\n\treturn nil\n}\n\nfunc (m *Product) GetCategories() []string {\n\tif m != nil {\n\t\treturn m.Categories\n\t}\n\treturn nil\n}\n\ntype ListProductsResponse struct {\n\tProducts             []*Product `protobuf:\"bytes,1,rep,name=products,proto3\" json:\"products,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *ListProductsResponse) Reset()         { *m = ListProductsResponse{} }\nfunc (m *ListProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ListProductsResponse) ProtoMessage()    {}\nfunc (*ListProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{9}\n}\n\nfunc (m *ListProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ListProductsResponse.Unmarshal(m, b)\n}\nfunc (m *ListProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ListProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ListProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ListProductsResponse.Merge(m, src)\n}\nfunc (m *ListProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ListProductsResponse.Size(m)\n}\nfunc (m *ListProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ListProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ListProductsResponse proto.InternalMessageInfo\n\nfunc (m *ListProductsResponse) GetProducts() []*Product {\n\tif m != nil {\n\t\treturn m.Products\n\t}\n\treturn nil\n}\n\ntype GetProductRequest struct {\n\tId                   string   `protobuf:\"bytes,1,opt,name=id,proto3\" json:\"id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetProductRequest) Reset()         { *m = GetProductRequest{} }\nfunc (m *GetProductRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetProductRequest) ProtoMessage()    {}\nfunc (*GetProductRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{10}\n}\n\nfunc (m *GetProductRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetProductRequest.Unmarshal(m, b)\n}\nfunc (m *GetProductRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetProductRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetProductRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetProductRequest.Merge(m, src)\n}\nfunc (m *GetProductRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetProductRequest.Size(m)\n}\nfunc (m *GetProductRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetProductRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetProductRequest proto.InternalMessageInfo\n\nfunc (m *GetProductRequest) GetId() string {\n\tif m != nil {\n\t\treturn m.Id\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsRequest struct {\n\tQuery                string   `protobuf:\"bytes,1,opt,name=query,proto3\" json:\"query,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *SearchProductsRequest) Reset()         { *m = SearchProductsRequest{} }\nfunc (m *SearchProductsRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsRequest) ProtoMessage()    {}\nfunc (*SearchProductsRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{11}\n}\n\nfunc (m *SearchProductsRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsRequest.Unmarshal(m, b)\n}\nfunc (m *SearchProductsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsRequest.Merge(m, src)\n}\nfunc (m *SearchProductsRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsRequest.Size(m)\n}\nfunc (m *SearchProductsRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsRequest proto.InternalMessageInfo\n\nfunc (m *SearchProductsRequest) GetQuery() string {\n\tif m != nil {\n\t\treturn m.Query\n\t}\n\treturn \"\"\n}\n\ntype SearchProductsResponse struct {\n\tResults              []*Product `protobuf:\"bytes,1,rep,name=results,proto3\" json:\"results,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}   `json:\"-\"`\n\tXXX_unrecognized     []byte     `json:\"-\"`\n\tXXX_sizecache        int32      `json:\"-\"`\n}\n\nfunc (m *SearchProductsResponse) Reset()         { *m = SearchProductsResponse{} }\nfunc (m *SearchProductsResponse) String() string { return proto.CompactTextString(m) }\nfunc (*SearchProductsResponse) ProtoMessage()    {}\nfunc (*SearchProductsResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{12}\n}\n\nfunc (m *SearchProductsResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SearchProductsResponse.Unmarshal(m, b)\n}\nfunc (m *SearchProductsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SearchProductsResponse.Marshal(b, m, deterministic)\n}\nfunc (m *SearchProductsResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SearchProductsResponse.Merge(m, src)\n}\nfunc (m *SearchProductsResponse) XXX_Size() int {\n\treturn xxx_messageInfo_SearchProductsResponse.Size(m)\n}\nfunc (m *SearchProductsResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_SearchProductsResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SearchProductsResponse proto.InternalMessageInfo\n\nfunc (m *SearchProductsResponse) GetResults() []*Product {\n\tif m != nil {\n\t\treturn m.Results\n\t}\n\treturn nil\n}\n\ntype GetQuoteRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *GetQuoteRequest) Reset()         { *m = GetQuoteRequest{} }\nfunc (m *GetQuoteRequest) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteRequest) ProtoMessage()    {}\nfunc (*GetQuoteRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{13}\n}\n\nfunc (m *GetQuoteRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteRequest.Unmarshal(m, b)\n}\nfunc (m *GetQuoteRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteRequest.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteRequest.Merge(m, src)\n}\nfunc (m *GetQuoteRequest) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteRequest.Size(m)\n}\nfunc (m *GetQuoteRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteRequest proto.InternalMessageInfo\n\nfunc (m *GetQuoteRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *GetQuoteRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype GetQuoteResponse struct {\n\tCostUsd              *Money   `protobuf:\"bytes,1,opt,name=cost_usd,json=costUsd,proto3\" json:\"cost_usd,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetQuoteResponse) Reset()         { *m = GetQuoteResponse{} }\nfunc (m *GetQuoteResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetQuoteResponse) ProtoMessage()    {}\nfunc (*GetQuoteResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{14}\n}\n\nfunc (m *GetQuoteResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetQuoteResponse.Unmarshal(m, b)\n}\nfunc (m *GetQuoteResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetQuoteResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetQuoteResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetQuoteResponse.Merge(m, src)\n}\nfunc (m *GetQuoteResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetQuoteResponse.Size(m)\n}\nfunc (m *GetQuoteResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetQuoteResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetQuoteResponse proto.InternalMessageInfo\n\nfunc (m *GetQuoteResponse) GetCostUsd() *Money {\n\tif m != nil {\n\t\treturn m.CostUsd\n\t}\n\treturn nil\n}\n\ntype ShipOrderRequest struct {\n\tAddress              *Address    `protobuf:\"bytes,1,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tItems                []*CartItem `protobuf:\"bytes,2,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}    `json:\"-\"`\n\tXXX_unrecognized     []byte      `json:\"-\"`\n\tXXX_sizecache        int32       `json:\"-\"`\n}\n\nfunc (m *ShipOrderRequest) Reset()         { *m = ShipOrderRequest{} }\nfunc (m *ShipOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderRequest) ProtoMessage()    {}\nfunc (*ShipOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{15}\n}\n\nfunc (m *ShipOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderRequest.Unmarshal(m, b)\n}\nfunc (m *ShipOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderRequest.Merge(m, src)\n}\nfunc (m *ShipOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderRequest.Size(m)\n}\nfunc (m *ShipOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderRequest proto.InternalMessageInfo\n\nfunc (m *ShipOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *ShipOrderRequest) GetItems() []*CartItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype ShipOrderResponse struct {\n\tTrackingId           string   `protobuf:\"bytes,1,opt,name=tracking_id,json=trackingId,proto3\" json:\"tracking_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ShipOrderResponse) Reset()         { *m = ShipOrderResponse{} }\nfunc (m *ShipOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ShipOrderResponse) ProtoMessage()    {}\nfunc (*ShipOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{16}\n}\n\nfunc (m *ShipOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ShipOrderResponse.Unmarshal(m, b)\n}\nfunc (m *ShipOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ShipOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ShipOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ShipOrderResponse.Merge(m, src)\n}\nfunc (m *ShipOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ShipOrderResponse.Size(m)\n}\nfunc (m *ShipOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ShipOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ShipOrderResponse proto.InternalMessageInfo\n\nfunc (m *ShipOrderResponse) GetTrackingId() string {\n\tif m != nil {\n\t\treturn m.TrackingId\n\t}\n\treturn \"\"\n}\n\ntype Address struct {\n\tStreetAddress        string   `protobuf:\"bytes,1,opt,name=street_address,json=streetAddress,proto3\" json:\"street_address,omitempty\"`\n\tCity                 string   `protobuf:\"bytes,2,opt,name=city,proto3\" json:\"city,omitempty\"`\n\tState                string   `protobuf:\"bytes,3,opt,name=state,proto3\" json:\"state,omitempty\"`\n\tCountry              string   `protobuf:\"bytes,4,opt,name=country,proto3\" json:\"country,omitempty\"`\n\tZipCode              int32    `protobuf:\"varint,5,opt,name=zip_code,json=zipCode,proto3\" json:\"zip_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Address) Reset()         { *m = Address{} }\nfunc (m *Address) String() string { return proto.CompactTextString(m) }\nfunc (*Address) ProtoMessage()    {}\nfunc (*Address) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{17}\n}\n\nfunc (m *Address) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Address.Unmarshal(m, b)\n}\nfunc (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Address.Marshal(b, m, deterministic)\n}\nfunc (m *Address) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Address.Merge(m, src)\n}\nfunc (m *Address) XXX_Size() int {\n\treturn xxx_messageInfo_Address.Size(m)\n}\nfunc (m *Address) XXX_DiscardUnknown() {\n\txxx_messageInfo_Address.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Address proto.InternalMessageInfo\n\nfunc (m *Address) GetStreetAddress() string {\n\tif m != nil {\n\t\treturn m.StreetAddress\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCity() string {\n\tif m != nil {\n\t\treturn m.City\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetState() string {\n\tif m != nil {\n\t\treturn m.State\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetCountry() string {\n\tif m != nil {\n\t\treturn m.Country\n\t}\n\treturn \"\"\n}\n\nfunc (m *Address) GetZipCode() int32 {\n\tif m != nil {\n\t\treturn m.ZipCode\n\t}\n\treturn 0\n}\n\n// Represents an amount of money with its currency type.\ntype Money struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCode string `protobuf:\"bytes,1,opt,name=currency_code,json=currencyCode,proto3\" json:\"currency_code,omitempty\"`\n\t// The whole units of the amount.\n\t// For example if `currencyCode` is `\"USD\"`, then 1 unit is one US dollar.\n\tUnits int64 `protobuf:\"varint,2,opt,name=units,proto3\" json:\"units,omitempty\"`\n\t// Number of nano (10^-9) units of the amount.\n\t// The value must be between -999,999,999 and +999,999,999 inclusive.\n\t// If `units` is positive, `nanos` must be positive or zero.\n\t// If `units` is zero, `nanos` can be positive, zero, or negative.\n\t// If `units` is negative, `nanos` must be negative or zero.\n\t// For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.\n\tNanos                int32    `protobuf:\"varint,3,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Money) Reset()         { *m = Money{} }\nfunc (m *Money) String() string { return proto.CompactTextString(m) }\nfunc (*Money) ProtoMessage()    {}\nfunc (*Money) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{18}\n}\n\nfunc (m *Money) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Money.Unmarshal(m, b)\n}\nfunc (m *Money) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Money.Marshal(b, m, deterministic)\n}\nfunc (m *Money) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Money.Merge(m, src)\n}\nfunc (m *Money) XXX_Size() int {\n\treturn xxx_messageInfo_Money.Size(m)\n}\nfunc (m *Money) XXX_DiscardUnknown() {\n\txxx_messageInfo_Money.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Money proto.InternalMessageInfo\n\nfunc (m *Money) GetCurrencyCode() string {\n\tif m != nil {\n\t\treturn m.CurrencyCode\n\t}\n\treturn \"\"\n}\n\nfunc (m *Money) GetUnits() int64 {\n\tif m != nil {\n\t\treturn m.Units\n\t}\n\treturn 0\n}\n\nfunc (m *Money) GetNanos() int32 {\n\tif m != nil {\n\t\treturn m.Nanos\n\t}\n\treturn 0\n}\n\ntype GetSupportedCurrenciesResponse struct {\n\t// The 3-letter currency code defined in ISO 4217.\n\tCurrencyCodes        []string `protobuf:\"bytes,1,rep,name=currency_codes,json=currencyCodes,proto3\" json:\"currency_codes,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *GetSupportedCurrenciesResponse) Reset()         { *m = GetSupportedCurrenciesResponse{} }\nfunc (m *GetSupportedCurrenciesResponse) String() string { return proto.CompactTextString(m) }\nfunc (*GetSupportedCurrenciesResponse) ProtoMessage()    {}\nfunc (*GetSupportedCurrenciesResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{19}\n}\n\nfunc (m *GetSupportedCurrenciesResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Unmarshal(m, b)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Marshal(b, m, deterministic)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.Merge(m, src)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_Size() int {\n\treturn xxx_messageInfo_GetSupportedCurrenciesResponse.Size(m)\n}\nfunc (m *GetSupportedCurrenciesResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_GetSupportedCurrenciesResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_GetSupportedCurrenciesResponse proto.InternalMessageInfo\n\nfunc (m *GetSupportedCurrenciesResponse) GetCurrencyCodes() []string {\n\tif m != nil {\n\t\treturn m.CurrencyCodes\n\t}\n\treturn nil\n}\n\ntype CurrencyConversionRequest struct {\n\tFrom *Money `protobuf:\"bytes,1,opt,name=from,proto3\" json:\"from,omitempty\"`\n\t// The 3-letter currency code defined in ISO 4217.\n\tToCode               string   `protobuf:\"bytes,2,opt,name=to_code,json=toCode,proto3\" json:\"to_code,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *CurrencyConversionRequest) Reset()         { *m = CurrencyConversionRequest{} }\nfunc (m *CurrencyConversionRequest) String() string { return proto.CompactTextString(m) }\nfunc (*CurrencyConversionRequest) ProtoMessage()    {}\nfunc (*CurrencyConversionRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{20}\n}\n\nfunc (m *CurrencyConversionRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Unmarshal(m, b)\n}\nfunc (m *CurrencyConversionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Marshal(b, m, deterministic)\n}\nfunc (m *CurrencyConversionRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CurrencyConversionRequest.Merge(m, src)\n}\nfunc (m *CurrencyConversionRequest) XXX_Size() int {\n\treturn xxx_messageInfo_CurrencyConversionRequest.Size(m)\n}\nfunc (m *CurrencyConversionRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_CurrencyConversionRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CurrencyConversionRequest proto.InternalMessageInfo\n\nfunc (m *CurrencyConversionRequest) GetFrom() *Money {\n\tif m != nil {\n\t\treturn m.From\n\t}\n\treturn nil\n}\n\nfunc (m *CurrencyConversionRequest) GetToCode() string {\n\tif m != nil {\n\t\treturn m.ToCode\n\t}\n\treturn \"\"\n}\n\ntype CreditCardInfo struct {\n\tCreditCardNumber          string   `protobuf:\"bytes,1,opt,name=credit_card_number,json=creditCardNumber,proto3\" json:\"credit_card_number,omitempty\"`\n\tCreditCardCvv             int32    `protobuf:\"varint,2,opt,name=credit_card_cvv,json=creditCardCvv,proto3\" json:\"credit_card_cvv,omitempty\"`\n\tCreditCardExpirationYear  int32    `protobuf:\"varint,3,opt,name=credit_card_expiration_year,json=creditCardExpirationYear,proto3\" json:\"credit_card_expiration_year,omitempty\"`\n\tCreditCardExpirationMonth int32    `protobuf:\"varint,4,opt,name=credit_card_expiration_month,json=creditCardExpirationMonth,proto3\" json:\"credit_card_expiration_month,omitempty\"`\n\tXXX_NoUnkeyedLiteral      struct{} `json:\"-\"`\n\tXXX_unrecognized          []byte   `json:\"-\"`\n\tXXX_sizecache             int32    `json:\"-\"`\n}\n\nfunc (m *CreditCardInfo) Reset()         { *m = CreditCardInfo{} }\nfunc (m *CreditCardInfo) String() string { return proto.CompactTextString(m) }\nfunc (*CreditCardInfo) ProtoMessage()    {}\nfunc (*CreditCardInfo) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{21}\n}\n\nfunc (m *CreditCardInfo) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_CreditCardInfo.Unmarshal(m, b)\n}\nfunc (m *CreditCardInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_CreditCardInfo.Marshal(b, m, deterministic)\n}\nfunc (m *CreditCardInfo) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_CreditCardInfo.Merge(m, src)\n}\nfunc (m *CreditCardInfo) XXX_Size() int {\n\treturn xxx_messageInfo_CreditCardInfo.Size(m)\n}\nfunc (m *CreditCardInfo) XXX_DiscardUnknown() {\n\txxx_messageInfo_CreditCardInfo.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_CreditCardInfo proto.InternalMessageInfo\n\nfunc (m *CreditCardInfo) GetCreditCardNumber() string {\n\tif m != nil {\n\t\treturn m.CreditCardNumber\n\t}\n\treturn \"\"\n}\n\nfunc (m *CreditCardInfo) GetCreditCardCvv() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardCvv\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationYear() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationYear\n\t}\n\treturn 0\n}\n\nfunc (m *CreditCardInfo) GetCreditCardExpirationMonth() int32 {\n\tif m != nil {\n\t\treturn m.CreditCardExpirationMonth\n\t}\n\treturn 0\n}\n\ntype ChargeRequest struct {\n\tAmount               *Money          `protobuf:\"bytes,1,opt,name=amount,proto3\" json:\"amount,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,2,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *ChargeRequest) Reset()         { *m = ChargeRequest{} }\nfunc (m *ChargeRequest) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeRequest) ProtoMessage()    {}\nfunc (*ChargeRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{22}\n}\n\nfunc (m *ChargeRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeRequest.Unmarshal(m, b)\n}\nfunc (m *ChargeRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeRequest.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeRequest.Merge(m, src)\n}\nfunc (m *ChargeRequest) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeRequest.Size(m)\n}\nfunc (m *ChargeRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeRequest proto.InternalMessageInfo\n\nfunc (m *ChargeRequest) GetAmount() *Money {\n\tif m != nil {\n\t\treturn m.Amount\n\t}\n\treturn nil\n}\n\nfunc (m *ChargeRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype ChargeResponse struct {\n\tTransactionId        string   `protobuf:\"bytes,1,opt,name=transaction_id,json=transactionId,proto3\" json:\"transaction_id,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *ChargeResponse) Reset()         { *m = ChargeResponse{} }\nfunc (m *ChargeResponse) String() string { return proto.CompactTextString(m) }\nfunc (*ChargeResponse) ProtoMessage()    {}\nfunc (*ChargeResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{23}\n}\n\nfunc (m *ChargeResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_ChargeResponse.Unmarshal(m, b)\n}\nfunc (m *ChargeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_ChargeResponse.Marshal(b, m, deterministic)\n}\nfunc (m *ChargeResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_ChargeResponse.Merge(m, src)\n}\nfunc (m *ChargeResponse) XXX_Size() int {\n\treturn xxx_messageInfo_ChargeResponse.Size(m)\n}\nfunc (m *ChargeResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_ChargeResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_ChargeResponse proto.InternalMessageInfo\n\nfunc (m *ChargeResponse) GetTransactionId() string {\n\tif m != nil {\n\t\treturn m.TransactionId\n\t}\n\treturn \"\"\n}\n\ntype OrderItem struct {\n\tItem                 *CartItem `protobuf:\"bytes,1,opt,name=item,proto3\" json:\"item,omitempty\"`\n\tCost                 *Money    `protobuf:\"bytes,2,opt,name=cost,proto3\" json:\"cost,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}  `json:\"-\"`\n\tXXX_unrecognized     []byte    `json:\"-\"`\n\tXXX_sizecache        int32     `json:\"-\"`\n}\n\nfunc (m *OrderItem) Reset()         { *m = OrderItem{} }\nfunc (m *OrderItem) String() string { return proto.CompactTextString(m) }\nfunc (*OrderItem) ProtoMessage()    {}\nfunc (*OrderItem) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{24}\n}\n\nfunc (m *OrderItem) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderItem.Unmarshal(m, b)\n}\nfunc (m *OrderItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderItem.Marshal(b, m, deterministic)\n}\nfunc (m *OrderItem) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderItem.Merge(m, src)\n}\nfunc (m *OrderItem) XXX_Size() int {\n\treturn xxx_messageInfo_OrderItem.Size(m)\n}\nfunc (m *OrderItem) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderItem.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderItem proto.InternalMessageInfo\n\nfunc (m *OrderItem) GetItem() *CartItem {\n\tif m != nil {\n\t\treturn m.Item\n\t}\n\treturn nil\n}\n\nfunc (m *OrderItem) GetCost() *Money {\n\tif m != nil {\n\t\treturn m.Cost\n\t}\n\treturn nil\n}\n\ntype OrderResult struct {\n\tOrderId              string       `protobuf:\"bytes,1,opt,name=order_id,json=orderId,proto3\" json:\"order_id,omitempty\"`\n\tShippingTrackingId   string       `protobuf:\"bytes,2,opt,name=shipping_tracking_id,json=shippingTrackingId,proto3\" json:\"shipping_tracking_id,omitempty\"`\n\tShippingCost         *Money       `protobuf:\"bytes,3,opt,name=shipping_cost,json=shippingCost,proto3\" json:\"shipping_cost,omitempty\"`\n\tShippingAddress      *Address     `protobuf:\"bytes,4,opt,name=shipping_address,json=shippingAddress,proto3\" json:\"shipping_address,omitempty\"`\n\tItems                []*OrderItem `protobuf:\"bytes,5,rep,name=items,proto3\" json:\"items,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *OrderResult) Reset()         { *m = OrderResult{} }\nfunc (m *OrderResult) String() string { return proto.CompactTextString(m) }\nfunc (*OrderResult) ProtoMessage()    {}\nfunc (*OrderResult) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{25}\n}\n\nfunc (m *OrderResult) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_OrderResult.Unmarshal(m, b)\n}\nfunc (m *OrderResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_OrderResult.Marshal(b, m, deterministic)\n}\nfunc (m *OrderResult) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_OrderResult.Merge(m, src)\n}\nfunc (m *OrderResult) XXX_Size() int {\n\treturn xxx_messageInfo_OrderResult.Size(m)\n}\nfunc (m *OrderResult) XXX_DiscardUnknown() {\n\txxx_messageInfo_OrderResult.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_OrderResult proto.InternalMessageInfo\n\nfunc (m *OrderResult) GetOrderId() string {\n\tif m != nil {\n\t\treturn m.OrderId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingTrackingId() string {\n\tif m != nil {\n\t\treturn m.ShippingTrackingId\n\t}\n\treturn \"\"\n}\n\nfunc (m *OrderResult) GetShippingCost() *Money {\n\tif m != nil {\n\t\treturn m.ShippingCost\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetShippingAddress() *Address {\n\tif m != nil {\n\t\treturn m.ShippingAddress\n\t}\n\treturn nil\n}\n\nfunc (m *OrderResult) GetItems() []*OrderItem {\n\tif m != nil {\n\t\treturn m.Items\n\t}\n\treturn nil\n}\n\ntype SendOrderConfirmationRequest struct {\n\tEmail                string       `protobuf:\"bytes,1,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tOrder                *OrderResult `protobuf:\"bytes,2,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *SendOrderConfirmationRequest) Reset()         { *m = SendOrderConfirmationRequest{} }\nfunc (m *SendOrderConfirmationRequest) String() string { return proto.CompactTextString(m) }\nfunc (*SendOrderConfirmationRequest) ProtoMessage()    {}\nfunc (*SendOrderConfirmationRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{26}\n}\n\nfunc (m *SendOrderConfirmationRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Unmarshal(m, b)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Marshal(b, m, deterministic)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_SendOrderConfirmationRequest.Merge(m, src)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_Size() int {\n\treturn xxx_messageInfo_SendOrderConfirmationRequest.Size(m)\n}\nfunc (m *SendOrderConfirmationRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_SendOrderConfirmationRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_SendOrderConfirmationRequest proto.InternalMessageInfo\n\nfunc (m *SendOrderConfirmationRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *SendOrderConfirmationRequest) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype PlaceOrderRequest struct {\n\tUserId               string          `protobuf:\"bytes,1,opt,name=user_id,json=userId,proto3\" json:\"user_id,omitempty\"`\n\tUserCurrency         string          `protobuf:\"bytes,2,opt,name=user_currency,json=userCurrency,proto3\" json:\"user_currency,omitempty\"`\n\tAddress              *Address        `protobuf:\"bytes,3,opt,name=address,proto3\" json:\"address,omitempty\"`\n\tEmail                string          `protobuf:\"bytes,5,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tCreditCard           *CreditCardInfo `protobuf:\"bytes,6,opt,name=credit_card,json=creditCard,proto3\" json:\"credit_card,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}        `json:\"-\"`\n\tXXX_unrecognized     []byte          `json:\"-\"`\n\tXXX_sizecache        int32           `json:\"-\"`\n}\n\nfunc (m *PlaceOrderRequest) Reset()         { *m = PlaceOrderRequest{} }\nfunc (m *PlaceOrderRequest) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderRequest) ProtoMessage()    {}\nfunc (*PlaceOrderRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{27}\n}\n\nfunc (m *PlaceOrderRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderRequest.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderRequest.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderRequest.Merge(m, src)\n}\nfunc (m *PlaceOrderRequest) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderRequest.Size(m)\n}\nfunc (m *PlaceOrderRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderRequest proto.InternalMessageInfo\n\nfunc (m *PlaceOrderRequest) GetUserId() string {\n\tif m != nil {\n\t\treturn m.UserId\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetUserCurrency() string {\n\tif m != nil {\n\t\treturn m.UserCurrency\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetAddress() *Address {\n\tif m != nil {\n\t\treturn m.Address\n\t}\n\treturn nil\n}\n\nfunc (m *PlaceOrderRequest) GetEmail() string {\n\tif m != nil {\n\t\treturn m.Email\n\t}\n\treturn \"\"\n}\n\nfunc (m *PlaceOrderRequest) GetCreditCard() *CreditCardInfo {\n\tif m != nil {\n\t\treturn m.CreditCard\n\t}\n\treturn nil\n}\n\ntype PlaceOrderResponse struct {\n\tOrder                *OrderResult `protobuf:\"bytes,1,opt,name=order,proto3\" json:\"order,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{}     `json:\"-\"`\n\tXXX_unrecognized     []byte       `json:\"-\"`\n\tXXX_sizecache        int32        `json:\"-\"`\n}\n\nfunc (m *PlaceOrderResponse) Reset()         { *m = PlaceOrderResponse{} }\nfunc (m *PlaceOrderResponse) String() string { return proto.CompactTextString(m) }\nfunc (*PlaceOrderResponse) ProtoMessage()    {}\nfunc (*PlaceOrderResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{28}\n}\n\nfunc (m *PlaceOrderResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_PlaceOrderResponse.Unmarshal(m, b)\n}\nfunc (m *PlaceOrderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_PlaceOrderResponse.Marshal(b, m, deterministic)\n}\nfunc (m *PlaceOrderResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PlaceOrderResponse.Merge(m, src)\n}\nfunc (m *PlaceOrderResponse) XXX_Size() int {\n\treturn xxx_messageInfo_PlaceOrderResponse.Size(m)\n}\nfunc (m *PlaceOrderResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_PlaceOrderResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PlaceOrderResponse proto.InternalMessageInfo\n\nfunc (m *PlaceOrderResponse) GetOrder() *OrderResult {\n\tif m != nil {\n\t\treturn m.Order\n\t}\n\treturn nil\n}\n\ntype AdRequest struct {\n\t// List of important key words from the current page describing the context.\n\tContextKeys          []string `protobuf:\"bytes,1,rep,name=context_keys,json=contextKeys,proto3\" json:\"context_keys,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdRequest) Reset()         { *m = AdRequest{} }\nfunc (m *AdRequest) String() string { return proto.CompactTextString(m) }\nfunc (*AdRequest) ProtoMessage()    {}\nfunc (*AdRequest) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{29}\n}\n\nfunc (m *AdRequest) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdRequest.Unmarshal(m, b)\n}\nfunc (m *AdRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdRequest.Marshal(b, m, deterministic)\n}\nfunc (m *AdRequest) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdRequest.Merge(m, src)\n}\nfunc (m *AdRequest) XXX_Size() int {\n\treturn xxx_messageInfo_AdRequest.Size(m)\n}\nfunc (m *AdRequest) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdRequest.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdRequest proto.InternalMessageInfo\n\nfunc (m *AdRequest) GetContextKeys() []string {\n\tif m != nil {\n\t\treturn m.ContextKeys\n\t}\n\treturn nil\n}\n\ntype AdResponse struct {\n\tAds                  []*Ad    `protobuf:\"bytes,1,rep,name=ads,proto3\" json:\"ads,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *AdResponse) Reset()         { *m = AdResponse{} }\nfunc (m *AdResponse) String() string { return proto.CompactTextString(m) }\nfunc (*AdResponse) ProtoMessage()    {}\nfunc (*AdResponse) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{30}\n}\n\nfunc (m *AdResponse) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_AdResponse.Unmarshal(m, b)\n}\nfunc (m *AdResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_AdResponse.Marshal(b, m, deterministic)\n}\nfunc (m *AdResponse) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_AdResponse.Merge(m, src)\n}\nfunc (m *AdResponse) XXX_Size() int {\n\treturn xxx_messageInfo_AdResponse.Size(m)\n}\nfunc (m *AdResponse) XXX_DiscardUnknown() {\n\txxx_messageInfo_AdResponse.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_AdResponse proto.InternalMessageInfo\n\nfunc (m *AdResponse) GetAds() []*Ad {\n\tif m != nil {\n\t\treturn m.Ads\n\t}\n\treturn nil\n}\n\ntype Ad struct {\n\t// url to redirect to when an ad is clicked.\n\tRedirectUrl string `protobuf:\"bytes,1,opt,name=redirect_url,json=redirectUrl,proto3\" json:\"redirect_url,omitempty\"`\n\t// short advertisement text to display.\n\tText                 string   `protobuf:\"bytes,2,opt,name=text,proto3\" json:\"text,omitempty\"`\n\tXXX_NoUnkeyedLiteral struct{} `json:\"-\"`\n\tXXX_unrecognized     []byte   `json:\"-\"`\n\tXXX_sizecache        int32    `json:\"-\"`\n}\n\nfunc (m *Ad) Reset()         { *m = Ad{} }\nfunc (m *Ad) String() string { return proto.CompactTextString(m) }\nfunc (*Ad) ProtoMessage()    {}\nfunc (*Ad) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_ca53982754088a9d, []int{31}\n}\n\nfunc (m *Ad) XXX_Unmarshal(b []byte) error {\n\treturn xxx_messageInfo_Ad.Unmarshal(m, b)\n}\nfunc (m *Ad) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\treturn xxx_messageInfo_Ad.Marshal(b, m, deterministic)\n}\nfunc (m *Ad) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_Ad.Merge(m, src)\n}\nfunc (m *Ad) XXX_Size() int {\n\treturn xxx_messageInfo_Ad.Size(m)\n}\nfunc (m *Ad) XXX_DiscardUnknown() {\n\txxx_messageInfo_Ad.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_Ad proto.InternalMessageInfo\n\nfunc (m *Ad) GetRedirectUrl() string {\n\tif m != nil {\n\t\treturn m.RedirectUrl\n\t}\n\treturn \"\"\n}\n\nfunc (m *Ad) GetText() string {\n\tif m != nil {\n\t\treturn m.Text\n\t}\n\treturn \"\"\n}\n\nfunc init() {\n\tproto.RegisterType((*CartItem)(nil), \"hipstershop.CartItem\")\n\tproto.RegisterType((*AddItemRequest)(nil), \"hipstershop.AddItemRequest\")\n\tproto.RegisterType((*EmptyCartRequest)(nil), \"hipstershop.EmptyCartRequest\")\n\tproto.RegisterType((*GetCartRequest)(nil), \"hipstershop.GetCartRequest\")\n\tproto.RegisterType((*Cart)(nil), \"hipstershop.Cart\")\n\tproto.RegisterType((*Empty)(nil), \"hipstershop.Empty\")\n\tproto.RegisterType((*ListRecommendationsRequest)(nil), \"hipstershop.ListRecommendationsRequest\")\n\tproto.RegisterType((*ListRecommendationsResponse)(nil), \"hipstershop.ListRecommendationsResponse\")\n\tproto.RegisterType((*Product)(nil), \"hipstershop.Product\")\n\tproto.RegisterType((*ListProductsResponse)(nil), \"hipstershop.ListProductsResponse\")\n\tproto.RegisterType((*GetProductRequest)(nil), \"hipstershop.GetProductRequest\")\n\tproto.RegisterType((*SearchProductsRequest)(nil), \"hipstershop.SearchProductsRequest\")\n\tproto.RegisterType((*SearchProductsResponse)(nil), \"hipstershop.SearchProductsResponse\")\n\tproto.RegisterType((*GetQuoteRequest)(nil), \"hipstershop.GetQuoteRequest\")\n\tproto.RegisterType((*GetQuoteResponse)(nil), \"hipstershop.GetQuoteResponse\")\n\tproto.RegisterType((*ShipOrderRequest)(nil), \"hipstershop.ShipOrderRequest\")\n\tproto.RegisterType((*ShipOrderResponse)(nil), \"hipstershop.ShipOrderResponse\")\n\tproto.RegisterType((*Address)(nil), \"hipstershop.Address\")\n\tproto.RegisterType((*Money)(nil), \"hipstershop.Money\")\n\tproto.RegisterType((*GetSupportedCurrenciesResponse)(nil), \"hipstershop.GetSupportedCurrenciesResponse\")\n\tproto.RegisterType((*CurrencyConversionRequest)(nil), \"hipstershop.CurrencyConversionRequest\")\n\tproto.RegisterType((*CreditCardInfo)(nil), \"hipstershop.CreditCardInfo\")\n\tproto.RegisterType((*ChargeRequest)(nil), \"hipstershop.ChargeRequest\")\n\tproto.RegisterType((*ChargeResponse)(nil), \"hipstershop.ChargeResponse\")\n\tproto.RegisterType((*OrderItem)(nil), \"hipstershop.OrderItem\")\n\tproto.RegisterType((*OrderResult)(nil), \"hipstershop.OrderResult\")\n\tproto.RegisterType((*SendOrderConfirmationRequest)(nil), \"hipstershop.SendOrderConfirmationRequest\")\n\tproto.RegisterType((*PlaceOrderRequest)(nil), \"hipstershop.PlaceOrderRequest\")\n\tproto.RegisterType((*PlaceOrderResponse)(nil), \"hipstershop.PlaceOrderResponse\")\n\tproto.RegisterType((*AdRequest)(nil), \"hipstershop.AdRequest\")\n\tproto.RegisterType((*AdResponse)(nil), \"hipstershop.AdResponse\")\n\tproto.RegisterType((*Ad)(nil), \"hipstershop.Ad\")\n}\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ context.Context\nvar _ grpc.ClientConn\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the grpc package it is being compiled against.\nconst _ = grpc.SupportPackageIsVersion4\n\n// CartServiceClient is the client API for CartService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CartServiceClient interface {\n\tAddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error)\n\tGetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error)\n\tEmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype cartServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCartServiceClient(cc *grpc.ClientConn) CartServiceClient {\n\treturn &cartServiceClient{cc}\n}\n\nfunc (c *cartServiceClient) AddItem(ctx context.Context, in *AddItemRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/AddItem\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) GetCart(ctx context.Context, in *GetCartRequest, opts ...grpc.CallOption) (*Cart, error) {\n\tout := new(Cart)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/GetCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *cartServiceClient) EmptyCart(ctx context.Context, in *EmptyCartRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CartService/EmptyCart\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CartServiceServer is the server API for CartService service.\ntype CartServiceServer interface {\n\tAddItem(context.Context, *AddItemRequest) (*Empty, error)\n\tGetCart(context.Context, *GetCartRequest) (*Cart, error)\n\tEmptyCart(context.Context, *EmptyCartRequest) (*Empty, error)\n}\n\nfunc RegisterCartServiceServer(s *grpc.Server, srv CartServiceServer) {\n\ts.RegisterService(&_CartService_serviceDesc, srv)\n}\n\nfunc _CartService_AddItem_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AddItemRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/AddItem\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).AddItem(ctx, req.(*AddItemRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_GetCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/GetCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).GetCart(ctx, req.(*GetCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CartService_EmptyCart_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(EmptyCartRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CartService/EmptyCart\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CartServiceServer).EmptyCart(ctx, req.(*EmptyCartRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CartService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CartService\",\n\tHandlerType: (*CartServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"AddItem\",\n\t\t\tHandler:    _CartService_AddItem_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetCart\",\n\t\t\tHandler:    _CartService_GetCart_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"EmptyCart\",\n\t\t\tHandler:    _CartService_EmptyCart_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// RecommendationServiceClient is the client API for RecommendationService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype RecommendationServiceClient interface {\n\tListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error)\n}\n\ntype recommendationServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {\n\treturn &recommendationServiceClient{cc}\n}\n\nfunc (c *recommendationServiceClient) ListRecommendations(ctx context.Context, in *ListRecommendationsRequest, opts ...grpc.CallOption) (*ListRecommendationsResponse, error) {\n\tout := new(ListRecommendationsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.RecommendationService/ListRecommendations\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// RecommendationServiceServer is the server API for RecommendationService service.\ntype RecommendationServiceServer interface {\n\tListRecommendations(context.Context, *ListRecommendationsRequest) (*ListRecommendationsResponse, error)\n}\n\nfunc RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {\n\ts.RegisterService(&_RecommendationService_serviceDesc, srv)\n}\n\nfunc _RecommendationService_ListRecommendations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ListRecommendationsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.RecommendationService/ListRecommendations\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(RecommendationServiceServer).ListRecommendations(ctx, req.(*ListRecommendationsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _RecommendationService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.RecommendationService\",\n\tHandlerType: (*RecommendationServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListRecommendations\",\n\t\t\tHandler:    _RecommendationService_ListRecommendations_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ProductCatalogServiceClient is the client API for ProductCatalogService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ProductCatalogServiceClient interface {\n\tListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error)\n\tGetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error)\n\tSearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error)\n}\n\ntype productCatalogServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewProductCatalogServiceClient(cc *grpc.ClientConn) ProductCatalogServiceClient {\n\treturn &productCatalogServiceClient{cc}\n}\n\nfunc (c *productCatalogServiceClient) ListProducts(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListProductsResponse, error) {\n\tout := new(ListProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/ListProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) GetProduct(ctx context.Context, in *GetProductRequest, opts ...grpc.CallOption) (*Product, error) {\n\tout := new(Product)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/GetProduct\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *productCatalogServiceClient) SearchProducts(ctx context.Context, in *SearchProductsRequest, opts ...grpc.CallOption) (*SearchProductsResponse, error) {\n\tout := new(SearchProductsResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ProductCatalogService/SearchProducts\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ProductCatalogServiceServer is the server API for ProductCatalogService service.\ntype ProductCatalogServiceServer interface {\n\tListProducts(context.Context, *Empty) (*ListProductsResponse, error)\n\tGetProduct(context.Context, *GetProductRequest) (*Product, error)\n\tSearchProducts(context.Context, *SearchProductsRequest) (*SearchProductsResponse, error)\n}\n\nfunc RegisterProductCatalogServiceServer(s *grpc.Server, srv ProductCatalogServiceServer) {\n\ts.RegisterService(&_ProductCatalogService_serviceDesc, srv)\n}\n\nfunc _ProductCatalogService_ListProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/ListProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).ListProducts(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_GetProduct_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetProductRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/GetProduct\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).GetProduct(ctx, req.(*GetProductRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ProductCatalogService_SearchProducts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SearchProductsRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ProductCatalogService/SearchProducts\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ProductCatalogServiceServer).SearchProducts(ctx, req.(*SearchProductsRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ProductCatalogService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ProductCatalogService\",\n\tHandlerType: (*ProductCatalogServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"ListProducts\",\n\t\t\tHandler:    _ProductCatalogService_ListProducts_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"GetProduct\",\n\t\t\tHandler:    _ProductCatalogService_GetProduct_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"SearchProducts\",\n\t\t\tHandler:    _ProductCatalogService_SearchProducts_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// ShippingServiceClient is the client API for ShippingService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype ShippingServiceClient interface {\n\tGetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error)\n\tShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error)\n}\n\ntype shippingServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewShippingServiceClient(cc *grpc.ClientConn) ShippingServiceClient {\n\treturn &shippingServiceClient{cc}\n}\n\nfunc (c *shippingServiceClient) GetQuote(ctx context.Context, in *GetQuoteRequest, opts ...grpc.CallOption) (*GetQuoteResponse, error) {\n\tout := new(GetQuoteResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/GetQuote\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *shippingServiceClient) ShipOrder(ctx context.Context, in *ShipOrderRequest, opts ...grpc.CallOption) (*ShipOrderResponse, error) {\n\tout := new(ShipOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.ShippingService/ShipOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// ShippingServiceServer is the server API for ShippingService service.\ntype ShippingServiceServer interface {\n\tGetQuote(context.Context, *GetQuoteRequest) (*GetQuoteResponse, error)\n\tShipOrder(context.Context, *ShipOrderRequest) (*ShipOrderResponse, error)\n}\n\nfunc RegisterShippingServiceServer(s *grpc.Server, srv ShippingServiceServer) {\n\ts.RegisterService(&_ShippingService_serviceDesc, srv)\n}\n\nfunc _ShippingService_GetQuote_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(GetQuoteRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/GetQuote\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).GetQuote(ctx, req.(*GetQuoteRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _ShippingService_ShipOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ShipOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.ShippingService/ShipOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(ShippingServiceServer).ShipOrder(ctx, req.(*ShipOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _ShippingService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.ShippingService\",\n\tHandlerType: (*ShippingServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetQuote\",\n\t\t\tHandler:    _ShippingService_GetQuote_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"ShipOrder\",\n\t\t\tHandler:    _ShippingService_ShipOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CurrencyServiceClient is the client API for CurrencyService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CurrencyServiceClient interface {\n\tGetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error)\n\tConvert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error)\n}\n\ntype currencyServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCurrencyServiceClient(cc *grpc.ClientConn) CurrencyServiceClient {\n\treturn &currencyServiceClient{cc}\n}\n\nfunc (c *currencyServiceClient) GetSupportedCurrencies(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetSupportedCurrenciesResponse, error) {\n\tout := new(GetSupportedCurrenciesResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/GetSupportedCurrencies\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\nfunc (c *currencyServiceClient) Convert(ctx context.Context, in *CurrencyConversionRequest, opts ...grpc.CallOption) (*Money, error) {\n\tout := new(Money)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CurrencyService/Convert\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CurrencyServiceServer is the server API for CurrencyService service.\ntype CurrencyServiceServer interface {\n\tGetSupportedCurrencies(context.Context, *Empty) (*GetSupportedCurrenciesResponse, error)\n\tConvert(context.Context, *CurrencyConversionRequest) (*Money, error)\n}\n\nfunc RegisterCurrencyServiceServer(s *grpc.Server, srv CurrencyServiceServer) {\n\ts.RegisterService(&_CurrencyService_serviceDesc, srv)\n}\n\nfunc _CurrencyService_GetSupportedCurrencies_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(Empty)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/GetSupportedCurrencies\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).GetSupportedCurrencies(ctx, req.(*Empty))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nfunc _CurrencyService_Convert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(CurrencyConversionRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CurrencyService/Convert\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CurrencyServiceServer).Convert(ctx, req.(*CurrencyConversionRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CurrencyService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CurrencyService\",\n\tHandlerType: (*CurrencyServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetSupportedCurrencies\",\n\t\t\tHandler:    _CurrencyService_GetSupportedCurrencies_Handler,\n\t\t},\n\t\t{\n\t\t\tMethodName: \"Convert\",\n\t\t\tHandler:    _CurrencyService_Convert_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// PaymentServiceClient is the client API for PaymentService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype PaymentServiceClient interface {\n\tCharge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error)\n}\n\ntype paymentServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewPaymentServiceClient(cc *grpc.ClientConn) PaymentServiceClient {\n\treturn &paymentServiceClient{cc}\n}\n\nfunc (c *paymentServiceClient) Charge(ctx context.Context, in *ChargeRequest, opts ...grpc.CallOption) (*ChargeResponse, error) {\n\tout := new(ChargeResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.PaymentService/Charge\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// PaymentServiceServer is the server API for PaymentService service.\ntype PaymentServiceServer interface {\n\tCharge(context.Context, *ChargeRequest) (*ChargeResponse, error)\n}\n\nfunc RegisterPaymentServiceServer(s *grpc.Server, srv PaymentServiceServer) {\n\ts.RegisterService(&_PaymentService_serviceDesc, srv)\n}\n\nfunc _PaymentService_Charge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(ChargeRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.PaymentService/Charge\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(PaymentServiceServer).Charge(ctx, req.(*ChargeRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _PaymentService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.PaymentService\",\n\tHandlerType: (*PaymentServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"Charge\",\n\t\t\tHandler:    _PaymentService_Charge_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// EmailServiceClient is the client API for EmailService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype EmailServiceClient interface {\n\tSendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error)\n}\n\ntype emailServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewEmailServiceClient(cc *grpc.ClientConn) EmailServiceClient {\n\treturn &emailServiceClient{cc}\n}\n\nfunc (c *emailServiceClient) SendOrderConfirmation(ctx context.Context, in *SendOrderConfirmationRequest, opts ...grpc.CallOption) (*Empty, error) {\n\tout := new(Empty)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.EmailService/SendOrderConfirmation\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// EmailServiceServer is the server API for EmailService service.\ntype EmailServiceServer interface {\n\tSendOrderConfirmation(context.Context, *SendOrderConfirmationRequest) (*Empty, error)\n}\n\nfunc RegisterEmailServiceServer(s *grpc.Server, srv EmailServiceServer) {\n\ts.RegisterService(&_EmailService_serviceDesc, srv)\n}\n\nfunc _EmailService_SendOrderConfirmation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(SendOrderConfirmationRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.EmailService/SendOrderConfirmation\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(EmailServiceServer).SendOrderConfirmation(ctx, req.(*SendOrderConfirmationRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _EmailService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.EmailService\",\n\tHandlerType: (*EmailServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"SendOrderConfirmation\",\n\t\t\tHandler:    _EmailService_SendOrderConfirmation_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// CheckoutServiceClient is the client API for CheckoutService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype CheckoutServiceClient interface {\n\tPlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error)\n}\n\ntype checkoutServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewCheckoutServiceClient(cc *grpc.ClientConn) CheckoutServiceClient {\n\treturn &checkoutServiceClient{cc}\n}\n\nfunc (c *checkoutServiceClient) PlaceOrder(ctx context.Context, in *PlaceOrderRequest, opts ...grpc.CallOption) (*PlaceOrderResponse, error) {\n\tout := new(PlaceOrderResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.CheckoutService/PlaceOrder\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// CheckoutServiceServer is the server API for CheckoutService service.\ntype CheckoutServiceServer interface {\n\tPlaceOrder(context.Context, *PlaceOrderRequest) (*PlaceOrderResponse, error)\n}\n\nfunc RegisterCheckoutServiceServer(s *grpc.Server, srv CheckoutServiceServer) {\n\ts.RegisterService(&_CheckoutService_serviceDesc, srv)\n}\n\nfunc _CheckoutService_PlaceOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(PlaceOrderRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.CheckoutService/PlaceOrder\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(CheckoutServiceServer).PlaceOrder(ctx, req.(*PlaceOrderRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _CheckoutService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.CheckoutService\",\n\tHandlerType: (*CheckoutServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"PlaceOrder\",\n\t\t\tHandler:    _CheckoutService_PlaceOrder_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\n// AdServiceClient is the client API for AdService service.\n//\n// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.\ntype AdServiceClient interface {\n\tGetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error)\n}\n\ntype adServiceClient struct {\n\tcc *grpc.ClientConn\n}\n\nfunc NewAdServiceClient(cc *grpc.ClientConn) AdServiceClient {\n\treturn &adServiceClient{cc}\n}\n\nfunc (c *adServiceClient) GetAds(ctx context.Context, in *AdRequest, opts ...grpc.CallOption) (*AdResponse, error) {\n\tout := new(AdResponse)\n\terr := c.cc.Invoke(ctx, \"/hipstershop.AdService/GetAds\", in, out, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn out, nil\n}\n\n// AdServiceServer is the server API for AdService service.\ntype AdServiceServer interface {\n\tGetAds(context.Context, *AdRequest) (*AdResponse, error)\n}\n\nfunc RegisterAdServiceServer(s *grpc.Server, srv AdServiceServer) {\n\ts.RegisterService(&_AdService_serviceDesc, srv)\n}\n\nfunc _AdService_GetAds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {\n\tin := new(AdRequest)\n\tif err := dec(in); err != nil {\n\t\treturn nil, err\n\t}\n\tif interceptor == nil {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, in)\n\t}\n\tinfo := &grpc.UnaryServerInfo{\n\t\tServer:     srv,\n\t\tFullMethod: \"/hipstershop.AdService/GetAds\",\n\t}\n\thandler := func(ctx context.Context, req interface{}) (interface{}, error) {\n\t\treturn srv.(AdServiceServer).GetAds(ctx, req.(*AdRequest))\n\t}\n\treturn interceptor(ctx, in, info, handler)\n}\n\nvar _AdService_serviceDesc = grpc.ServiceDesc{\n\tServiceName: \"hipstershop.AdService\",\n\tHandlerType: (*AdServiceServer)(nil),\n\tMethods: []grpc.MethodDesc{\n\t\t{\n\t\t\tMethodName: \"GetAds\",\n\t\t\tHandler:    _AdService_GetAds_Handler,\n\t\t},\n\t},\n\tStreams:  []grpc.StreamDesc{},\n\tMetadata: \"demo.proto\",\n}\n\nfunc init() { proto.RegisterFile(\"demo.proto\", fileDescriptor_ca53982754088a9d) }\n\nvar fileDescriptor_ca53982754088a9d = []byte{\n\t// 1500 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xef, 0x72, 0x13, 0xb7,\n\t0x16, 0xcf, 0x26, 0xb1, 0x1d, 0x1f, 0xc7, 0x4e, 0xa2, 0x9b, 0x04, 0xb3, 0x81, 0x10, 0x94, 0x81,\n\t0x0b, 0x17, 0x08, 0x4c, 0xee, 0x9d, 0xe1, 0x03, 0xdc, 0xd2, 0x8c, 0xc9, 0x18, 0x4f, 0xa1, 0xd0,\n\t0x0d, 0xe9, 0xd0, 0xa1, 0x53, 0xcf, 0xb2, 0x12, 0xf1, 0x96, 0xec, 0x6a, 0x91, 0xb4, 0x19, 0xcc,\n\t0xc7, 0xf6, 0x01, 0xfa, 0x1e, 0x7d, 0x81, 0xce, 0xf4, 0x11, 0xfa, 0xbd, 0xaf, 0xd0, 0xe7, 0xe8,\n\t0x48, 0xbb, 0xda, 0x7f, 0xb1, 0x13, 0xf8, 0xd2, 0x6f, 0xab, 0xa3, 0x9f, 0xce, 0xf9, 0xe9, 0xe8,\n\t0xfc, 0xb3, 0x01, 0x08, 0x0d, 0xd8, 0x4e, 0xc4, 0x99, 0x64, 0xa8, 0x35, 0xf2, 0x23, 0x21, 0x29,\n\t0x17, 0x23, 0x16, 0xe1, 0x7d, 0x58, 0xe8, 0xb9, 0x5c, 0x0e, 0x24, 0x0d, 0xd0, 0x65, 0x80, 0x88,\n\t0x33, 0x12, 0x7b, 0x72, 0xe8, 0x93, 0xae, 0xb5, 0x65, 0xdd, 0x68, 0x3a, 0xcd, 0x54, 0x32, 0x20,\n\t0xc8, 0x86, 0x85, 0xf7, 0xb1, 0x1b, 0x4a, 0x5f, 0x8e, 0xbb, 0xb3, 0x5b, 0xd6, 0x8d, 0x9a, 0x93,\n\t0xad, 0xf1, 0x4b, 0xe8, 0xec, 0x11, 0xa2, 0xb4, 0x38, 0xf4, 0x7d, 0x4c, 0x85, 0x44, 0x17, 0xa0,\n\t0x11, 0x0b, 0xca, 0x73, 0x4d, 0x75, 0xb5, 0x1c, 0x10, 0x74, 0x13, 0xe6, 0x7d, 0x49, 0x03, 0xad,\n\t0xa2, 0xb5, 0xbb, 0xb6, 0x53, 0x60, 0xb3, 0x63, 0xa8, 0x38, 0x1a, 0x82, 0x6f, 0xc1, 0xf2, 0x7e,\n\t0x10, 0xc9, 0xb1, 0x12, 0x9f, 0xa7, 0x17, 0xdf, 0x84, 0x4e, 0x9f, 0xca, 0x4f, 0x82, 0x3e, 0x85,\n\t0x79, 0x85, 0x9b, 0xce, 0xf1, 0x16, 0xd4, 0x14, 0x01, 0xd1, 0x9d, 0xdd, 0x9a, 0x9b, 0x4e, 0x32,\n\t0xc1, 0xe0, 0x06, 0xd4, 0x34, 0x4b, 0xfc, 0x2d, 0xd8, 0x4f, 0x7d, 0x21, 0x1d, 0xea, 0xb1, 0x20,\n\t0xa0, 0x21, 0x71, 0xa5, 0xcf, 0x42, 0x71, 0xae, 0x43, 0xae, 0x40, 0x2b, 0x77, 0x7b, 0x62, 0xb2,\n\t0xe9, 0x40, 0xe6, 0x77, 0x81, 0xbf, 0x80, 0x8d, 0x89, 0x7a, 0x45, 0xc4, 0x42, 0x41, 0xab, 0xe7,\n\t0xad, 0x53, 0xe7, 0x7f, 0xb7, 0xa0, 0xf1, 0x22, 0x59, 0xa2, 0x0e, 0xcc, 0x66, 0x04, 0x66, 0x7d,\n\t0x82, 0x10, 0xcc, 0x87, 0x6e, 0x40, 0xf5, 0x6b, 0x34, 0x1d, 0xfd, 0x8d, 0xb6, 0xa0, 0x45, 0xa8,\n\t0xf0, 0xb8, 0x1f, 0x29, 0x43, 0xdd, 0x39, 0xbd, 0x55, 0x14, 0xa1, 0x2e, 0x34, 0x22, 0xdf, 0x93,\n\t0x31, 0xa7, 0xdd, 0x79, 0xbd, 0x6b, 0x96, 0xe8, 0x2e, 0x34, 0x23, 0xee, 0x7b, 0x74, 0x18, 0x0b,\n\t0xd2, 0xad, 0xe9, 0x27, 0x46, 0x25, 0xef, 0x3d, 0x63, 0x21, 0x1d, 0x3b, 0x0b, 0x1a, 0x74, 0x28,\n\t0x08, 0xda, 0x04, 0xf0, 0x5c, 0x49, 0x8f, 0x18, 0xf7, 0xa9, 0xe8, 0xd6, 0x13, 0xf2, 0xb9, 0x04,\n\t0x3f, 0x81, 0x55, 0x75, 0xf9, 0x94, 0x7f, 0x7e, 0xeb, 0x7b, 0xb0, 0x90, 0x5e, 0x31, 0xb9, 0x72,\n\t0x6b, 0x77, 0xb5, 0x64, 0x27, 0x3d, 0xe0, 0x64, 0x28, 0xbc, 0x0d, 0x2b, 0x7d, 0x6a, 0x14, 0x99,\n\t0x57, 0xa9, 0xf8, 0x03, 0xdf, 0x81, 0xb5, 0x03, 0xea, 0x72, 0x6f, 0x94, 0x1b, 0x4c, 0x80, 0xab,\n\t0x50, 0x7b, 0x1f, 0x53, 0x3e, 0x4e, 0xb1, 0xc9, 0x02, 0x3f, 0x81, 0xf5, 0x2a, 0x3c, 0xe5, 0xb7,\n\t0x03, 0x0d, 0x4e, 0x45, 0x7c, 0x7c, 0x0e, 0x3d, 0x03, 0xc2, 0x21, 0x2c, 0xf5, 0xa9, 0xfc, 0x26,\n\t0x66, 0x92, 0x1a, 0x93, 0x3b, 0xd0, 0x70, 0x09, 0xe1, 0x54, 0x08, 0x6d, 0xb4, 0xaa, 0x62, 0x2f,\n\t0xd9, 0x73, 0x0c, 0xe8, 0xf3, 0xa2, 0x76, 0x0f, 0x96, 0x73, 0x7b, 0x29, 0xe7, 0x3b, 0xb0, 0xe0,\n\t0x31, 0x21, 0xf5, 0xdb, 0x59, 0x53, 0xdf, 0xae, 0xa1, 0x30, 0x87, 0x82, 0x60, 0x06, 0xcb, 0x07,\n\t0x23, 0x3f, 0x7a, 0xce, 0x09, 0xe5, 0xff, 0x08, 0xe7, 0xff, 0xc1, 0x4a, 0xc1, 0x60, 0x1e, 0xfe,\n\t0x92, 0xbb, 0xde, 0x3b, 0x3f, 0x3c, 0xca, 0x73, 0x0b, 0x8c, 0x68, 0x40, 0xf0, 0x2f, 0x16, 0x34,\n\t0x52, 0xbb, 0xe8, 0x1a, 0x74, 0x84, 0xe4, 0x94, 0xca, 0x61, 0x91, 0x65, 0xd3, 0x69, 0x27, 0x52,\n\t0x03, 0x43, 0x30, 0xef, 0x99, 0x32, 0xd7, 0x74, 0xf4, 0xb7, 0x0a, 0x00, 0x21, 0x5d, 0x49, 0xd3,\n\t0x7c, 0x48, 0x16, 0x2a, 0x13, 0x3c, 0x16, 0x87, 0x92, 0x8f, 0x4d, 0x26, 0xa4, 0x4b, 0x74, 0x11,\n\t0x16, 0x3e, 0xfa, 0xd1, 0xd0, 0x63, 0x84, 0xea, 0x44, 0xa8, 0x39, 0x8d, 0x8f, 0x7e, 0xd4, 0x63,\n\t0x84, 0xe2, 0x57, 0x50, 0xd3, 0xae, 0x44, 0xdb, 0xd0, 0xf6, 0x62, 0xce, 0x69, 0xe8, 0x8d, 0x13,\n\t0x60, 0xc2, 0x66, 0xd1, 0x08, 0x15, 0x5a, 0x19, 0x8e, 0x43, 0x5f, 0x0a, 0xcd, 0x66, 0xce, 0x49,\n\t0x16, 0x4a, 0x1a, 0xba, 0x21, 0x13, 0x9a, 0x4e, 0xcd, 0x49, 0x16, 0xb8, 0x0f, 0x9b, 0x7d, 0x2a,\n\t0x0f, 0xe2, 0x28, 0x62, 0x5c, 0x52, 0xd2, 0x4b, 0xf4, 0xf8, 0x34, 0x8f, 0xcb, 0x6b, 0xd0, 0x29,\n\t0x99, 0x34, 0x05, 0xa3, 0x5d, 0xb4, 0x29, 0xf0, 0xf7, 0x70, 0xb1, 0x97, 0x09, 0xc2, 0x13, 0xca,\n\t0x85, 0xcf, 0x42, 0xf3, 0xc8, 0xd7, 0x61, 0xfe, 0x2d, 0x67, 0xc1, 0x19, 0x31, 0xa2, 0xf7, 0x55,\n\t0xc9, 0x93, 0x2c, 0xb9, 0x58, 0xe2, 0xc9, 0xba, 0x64, 0xda, 0x01, 0x7f, 0x59, 0xd0, 0xe9, 0x71,\n\t0x4a, 0x7c, 0x55, 0xaf, 0xc9, 0x20, 0x7c, 0xcb, 0xd0, 0x6d, 0x40, 0x9e, 0x96, 0x0c, 0x3d, 0x97,\n\t0x93, 0x61, 0x18, 0x07, 0x6f, 0x28, 0x4f, 0xfd, 0xb1, 0xec, 0x65, 0xd8, 0xaf, 0xb5, 0x1c, 0x5d,\n\t0x87, 0xa5, 0x22, 0xda, 0x3b, 0x39, 0x49, 0x5b, 0x52, 0x3b, 0x87, 0xf6, 0x4e, 0x4e, 0xd0, 0xff,\n\t0x61, 0xa3, 0x88, 0xa3, 0x1f, 0x22, 0x9f, 0xeb, 0xf2, 0x39, 0x1c, 0x53, 0x97, 0xa7, 0xbe, 0xeb,\n\t0xe6, 0x67, 0xf6, 0x33, 0xc0, 0x77, 0xd4, 0xe5, 0xe8, 0x11, 0x5c, 0x9a, 0x72, 0x3c, 0x60, 0xa1,\n\t0x1c, 0xe9, 0x27, 0xaf, 0x39, 0x17, 0x27, 0x9d, 0x7f, 0xa6, 0x00, 0x78, 0x0c, 0xed, 0xde, 0xc8,\n\t0xe5, 0x47, 0x59, 0x4e, 0xff, 0x07, 0xea, 0x6e, 0xa0, 0x22, 0xe4, 0x0c, 0xe7, 0xa5, 0x08, 0xf4,\n\t0x10, 0x5a, 0x05, 0xeb, 0x69, 0xc3, 0xdc, 0x28, 0x67, 0x48, 0xc9, 0x89, 0x0e, 0xe4, 0x4c, 0xf0,\n\t0x7d, 0xe8, 0x18, 0xd3, 0xf9, 0xd3, 0x4b, 0xee, 0x86, 0xc2, 0xf5, 0xf4, 0x15, 0xb2, 0x64, 0x69,\n\t0x17, 0xa4, 0x03, 0x82, 0x7f, 0x80, 0xa6, 0xce, 0x30, 0x3d, 0x13, 0x98, 0x6e, 0x6d, 0x9d, 0xdb,\n\t0xad, 0x55, 0x54, 0xa8, 0xca, 0x90, 0xf2, 0x9c, 0x18, 0x15, 0x6a, 0x1f, 0xff, 0x34, 0x0b, 0x2d,\n\t0x93, 0xc2, 0xf1, 0xb1, 0x54, 0x89, 0xc2, 0xd4, 0x32, 0x27, 0xd4, 0xd0, 0xeb, 0x01, 0x41, 0xf7,\n\t0x60, 0x55, 0x8c, 0xfc, 0x28, 0x52, 0xb9, 0x5d, 0x4c, 0xf2, 0x24, 0x9a, 0x90, 0xd9, 0x7b, 0x99,\n\t0x25, 0x3b, 0xba, 0x0f, 0xed, 0xec, 0x84, 0x66, 0x33, 0x37, 0x95, 0xcd, 0xa2, 0x01, 0xf6, 0x98,\n\t0x90, 0xe8, 0x11, 0x2c, 0x67, 0x07, 0x4d, 0x6d, 0x98, 0x3f, 0xa3, 0x82, 0x2d, 0x19, 0xb4, 0xa9,\n\t0x19, 0xb7, 0x4d, 0x25, 0xab, 0xe9, 0x4a, 0xb6, 0x5e, 0x3a, 0x95, 0x39, 0xd4, 0x94, 0x32, 0x02,\n\t0x97, 0x0e, 0x68, 0x48, 0xb4, 0xbc, 0xc7, 0xc2, 0xb7, 0x3e, 0x0f, 0x74, 0xd8, 0x14, 0xda, 0x0d,\n\t0x0d, 0x5c, 0xff, 0xd8, 0xb4, 0x1b, 0xbd, 0x40, 0x3b, 0x50, 0xd3, 0xae, 0x49, 0x7d, 0xdc, 0x3d,\n\t0x6d, 0x23, 0xf1, 0xa9, 0x93, 0xc0, 0xf0, 0x9f, 0x16, 0xac, 0xbc, 0x38, 0x76, 0x3d, 0x5a, 0xaa,\n\t0xd1, 0x53, 0x27, 0x91, 0x6d, 0x68, 0xeb, 0x0d, 0x53, 0x0a, 0x52, 0x3f, 0x2f, 0x2a, 0xa1, 0xa9,\n\t0x06, 0xc5, 0x0a, 0x3f, 0xf7, 0x29, 0x15, 0x3e, 0xbb, 0x49, 0xad, 0x78, 0x93, 0x4a, 0x6c, 0xd7,\n\t0x3f, 0x2f, 0xb6, 0x1f, 0x03, 0x2a, 0x5e, 0x2b, 0x6b, 0xb9, 0xa9, 0x77, 0xac, 0x4f, 0xf3, 0xce,\n\t0x0e, 0x34, 0xf7, 0x88, 0x71, 0xca, 0x55, 0x58, 0xf4, 0x58, 0x28, 0xe9, 0x07, 0x39, 0x7c, 0x47,\n\t0xc7, 0xa6, 0x2a, 0xb6, 0x52, 0xd9, 0x57, 0x74, 0x2c, 0xf0, 0x5d, 0x00, 0x85, 0x4f, 0xad, 0x5d,\n\t0x85, 0x39, 0x97, 0x98, 0xe6, 0xbe, 0x54, 0xf1, 0x81, 0xa3, 0xf6, 0xf0, 0x03, 0x98, 0xdd, 0x23,\n\t0x4a, 0xb3, 0x62, 0xce, 0xa9, 0x27, 0x87, 0x31, 0x37, 0x2f, 0xda, 0x32, 0xb2, 0x43, 0x7e, 0xac,\n\t0xfa, 0x8d, 0xb2, 0x62, 0xfa, 0x8d, 0xfa, 0xde, 0xfd, 0xc3, 0x82, 0x96, 0xca, 0xb0, 0x03, 0xca,\n\t0x4f, 0x7c, 0x8f, 0xa2, 0x87, 0xba, 0x8b, 0xe9, 0xa4, 0xdc, 0xa8, 0x7a, 0xbc, 0x30, 0x78, 0xdb,\n\t0xe5, 0x50, 0x4f, 0x26, 0xd3, 0x19, 0xf4, 0x00, 0x1a, 0xe9, 0x74, 0x5c, 0x39, 0x5d, 0x9e, 0x99,\n\t0xed, 0x95, 0x53, 0x19, 0x8e, 0x67, 0xd0, 0x97, 0xd0, 0xcc, 0xe6, 0x70, 0x74, 0xf9, 0xb4, 0xfe,\n\t0xa2, 0x82, 0x89, 0xe6, 0x77, 0x7f, 0xb6, 0x60, 0xad, 0x3c, 0xbf, 0x9a, 0x6b, 0xfd, 0x08, 0xff,\n\t0x9a, 0x30, 0xdc, 0xa2, 0x7f, 0x97, 0xd4, 0x4c, 0x1f, 0xab, 0xed, 0x1b, 0xe7, 0x03, 0x93, 0x07,\n\t0x53, 0x2c, 0x66, 0x61, 0x2d, 0x1d, 0xbc, 0x7a, 0xae, 0x74, 0x8f, 0xd9, 0x91, 0x61, 0xd1, 0x87,\n\t0xc5, 0xe2, 0x94, 0x89, 0x26, 0xdc, 0xc2, 0xbe, 0x7a, 0xca, 0x52, 0x75, 0xe8, 0xc3, 0x33, 0xe8,\n\t0x31, 0x40, 0x3e, 0x64, 0xa2, 0xcd, 0xaa, 0xab, 0xcb, 0xd3, 0xa7, 0x3d, 0x71, 0x26, 0xc4, 0x33,\n\t0xe8, 0x35, 0x74, 0xca, 0x63, 0x25, 0xc2, 0x25, 0xe4, 0xc4, 0x11, 0xd5, 0xde, 0x3e, 0x13, 0x93,\n\t0x79, 0xe1, 0x57, 0x0b, 0x96, 0x0e, 0xd2, 0xe2, 0x65, 0xee, 0x3f, 0x80, 0x05, 0x33, 0x0d, 0xa2,\n\t0x4b, 0x55, 0xd2, 0xc5, 0xa1, 0xd4, 0xbe, 0x3c, 0x65, 0x37, 0xf3, 0xc0, 0x53, 0x68, 0x66, 0x43,\n\t0x5a, 0x25, 0x58, 0xaa, 0xd3, 0xa2, 0xbd, 0x39, 0x6d, 0x3b, 0x23, 0xfb, 0x9b, 0x05, 0x4b, 0xa6,\n\t0xf4, 0x18, 0xb2, 0xaf, 0x61, 0x7d, 0xf2, 0x90, 0x33, 0xf1, 0xd9, 0x6e, 0x55, 0x09, 0x9f, 0x31,\n\t0x1d, 0xe1, 0x19, 0xd4, 0x87, 0x46, 0x32, 0xf0, 0x48, 0x74, 0xbd, 0x9c, 0x0b, 0xd3, 0xc6, 0x21,\n\t0x7b, 0x42, 0x73, 0xc1, 0x33, 0xbb, 0x87, 0xd0, 0x79, 0xe1, 0x8e, 0x03, 0x1a, 0x66, 0x19, 0xdc,\n\t0x83, 0x7a, 0xd2, 0x91, 0x91, 0x5d, 0xd6, 0x5c, 0x9c, 0x10, 0xec, 0x8d, 0x89, 0x7b, 0x99, 0x43,\n\t0x46, 0xb0, 0xb8, 0xaf, 0x2a, 0xa8, 0x51, 0xfa, 0x4a, 0xfd, 0x60, 0x99, 0xd0, 0x48, 0xd0, 0xcd,\n\t0x4a, 0x34, 0x4c, 0x6f, 0x36, 0x53, 0x72, 0xf6, 0x0d, 0x2c, 0xf5, 0x46, 0xd4, 0x7b, 0xc7, 0xe2,\n\t0xec, 0x06, 0xcf, 0x01, 0xf2, 0xba, 0x5b, 0x89, 0xee, 0x53, 0x7d, 0xc6, 0xbe, 0x32, 0x75, 0x3f,\n\t0xbb, 0xcd, 0x13, 0x55, 0x82, 0x8d, 0xf6, 0x07, 0x50, 0xef, 0xab, 0x19, 0x5c, 0xa0, 0xf5, 0x6a,\n\t0x39, 0x4d, 0x35, 0x5e, 0x38, 0x25, 0x37, 0x9a, 0xde, 0xd4, 0xf5, 0x9f, 0x1b, 0xff, 0xfd, 0x3b,\n\t0x00, 0x00, 0xff, 0xff, 0xb2, 0xa0, 0x6e, 0x6c, 0xea, 0x10, 0x00, 0x00,\n}\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/genproto.sh",
    "content": "#!/bin/bash -eu\n#\n# Copyright 2018 Google LLC\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# [START gke_shippingservice_genproto]\n\nPATH=$PATH:$GOPATH/bin\nprotodir=../../pb\n\nprotoc --go_out=plugins=grpc:genproto -I $protodir $protodir/demo.proto\n\n# [END gke_shippingservice_genproto]"
  },
  {
    "path": "microservices-demo/src/shippingservice/go.mod",
    "content": "module github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice\n\ngo 1.18\n\nrequire (\n\tcloud.google.com/go/profiler v0.3.0\n\tcontrib.go.opencensus.io/exporter/jaeger v0.2.1\n\tcontrib.go.opencensus.io/exporter/stackdriver v0.13.12\n\tgithub.com/golang/protobuf v1.5.2\n\tgithub.com/sirupsen/logrus v1.8.1\n\tgo.opencensus.io v0.23.0\n\tgolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b\n\tgoogle.golang.org/grpc v1.48.0\n)\n\nrequire (\n\tcloud.google.com/go v0.100.2 // indirect\n\tcloud.google.com/go/compute v1.6.1 // indirect\n\tcloud.google.com/go/monitoring v1.1.0 // indirect\n\tcloud.google.com/go/trace v1.0.0 // indirect\n\tgithub.com/aws/aws-sdk-go v1.43.31 // indirect\n\tgithub.com/census-instrumentation/opencensus-proto v0.3.0 // indirect\n\tgithub.com/cespare/xxhash/v2 v2.1.1 // indirect\n\tgithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect\n\tgithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 // indirect\n\tgithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect\n\tgithub.com/envoyproxy/protoc-gen-validate v0.1.0 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/google/go-cmp v0.5.8 // indirect\n\tgithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f // indirect\n\tgithub.com/googleapis/gax-go/v2 v2.4.0 // indirect\n\tgithub.com/jmespath/go-jmespath v0.4.0 // indirect\n\tgithub.com/prometheus/prometheus v2.5.0+incompatible // indirect\n\tgithub.com/uber/jaeger-client-go v2.25.0+incompatible // indirect\n\tgolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect\n\tgolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect\n\tgolang.org/x/text v0.3.7 // indirect\n\tgoogle.golang.org/api v0.78.0 // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 // indirect\n\tgoogle.golang.org/protobuf v1.28.0 // indirect\n)\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=\ncloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=\ncloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=\ncloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=\ncloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=\ncloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=\ncloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=\ncloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=\ncloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=\ncloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=\ncloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=\ncloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=\ncloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY=\ncloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=\ncloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=\ncloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=\ncloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=\ncloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=\ncloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=\ncloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=\ncloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=\ncloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=\ncloud.google.com/go/monitoring v1.1.0 h1:ZnyNdf/XRcynMmKzRSNTOdOyYPs6G7do1l2D2hIvIKo=\ncloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4=\ncloud.google.com/go/profiler v0.1.1 h1:seMHZtcgOwZXAOKDZuW2sN3u1yKjYG19dUkElb4mbcQ=\ncloud.google.com/go/profiler v0.1.1/go.mod h1:zG22vSCuJKJMvIlLpX3FhNjOsifaoLdPAYc4yLw5Iw4=\ncloud.google.com/go/profiler v0.3.0 h1:R6y/xAeifaUXxd2x6w+jIwKxoKl8Cv5HJvcvASTPWJo=\ncloud.google.com/go/profiler v0.3.0/go.mod h1:9wYk9eY4iZHsev8TQb61kh3wiOiSyz/xOYixWPzweCU=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ncloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=\ncloud.google.com/go/trace v1.0.0 h1:laKx2y7IWMjguCe5zZx6n7qLtREk4kyE69SXVC0VSN8=\ncloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI=\ncontrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10 h1:a9+GZPUe+ONKUwULjlEOucMMG0qfSCCenlji0Nhqbys=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY=\ncontrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=\ngithub.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=\ngithub.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk=\ngithub.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=\ngithub.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0=\ngithub.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk=\ngithub.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=\ngithub.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI=\ngithub.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=\ngithub.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=\ngithub.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=\ngithub.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021 h1:fP+fF0up6oPY49OrjPrhIJ8yQfdIM85NXMLkMg1EXVs=\ngithub.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=\ngithub.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=\ngithub.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=\ngithub.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=\ngithub.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=\ngithub.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=\ngithub.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=\ngithub.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0 h1:zHs+jv3LO743/zFGcByu2KmpbliCU2AhjcGgrdTwSG4=\ngithub.com/google/pprof v0.0.0-20211008130755-947d60d73cc0/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f h1:VrKTY4lquiy1oJzVZgXrauku9Jx9P+POv/gTLakG4Wk=\ngithub.com/google/pprof v0.0.0-20220412212628-83db2b799d1f/go.mod h1:Pt31oes+eGImORns3McJn8zHefuQl2rG8l6xQjGYB4U=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=\ngithub.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=\ngithub.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=\ngithub.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=\ngithub.com/googleapis/gax-go/v2 v2.2.0 h1:s7jOdKSaksJVOxE0Y/S32otcfiP+UQ0cL8/GTKaONwE=\ngithub.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=\ngithub.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=\ngithub.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk=\ngithub.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=\ngithub.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=\ngithub.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=\ngithub.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=\ngithub.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=\ngithub.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg=\ngithub.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=\ngithub.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U=\ngithub.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=\ngo.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=\ngo.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=\ngo.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=\ngolang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=\ngolang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=\ngolang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be h1:yx80W7nvY5ySWpaU8UWaj5o9e23YgO9BRhQol7Lc+JI=\ngolang.org/x/net v0.0.0-20220420153159-1850ba15e1be/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=\ngolang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0=\ngolang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48 h1:N9Vc/rorQUDes6B9CNdIxAn5jODGj2wzfrei2x4wNj4=\ngolang.org/x/net v0.0.0-20220805013720-a33c5aa5df48/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs=\ngolang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw=\ngolang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=\ngolang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=\ngolang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=\ngolang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=\ngolang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=\ngolang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q=\ngolang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw=\ngolang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=\ngolang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=\ngolang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=\ngolang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=\ngoogle.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=\ngoogle.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=\ngoogle.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=\ngoogle.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=\ngoogle.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=\ngoogle.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=\ngoogle.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=\ngoogle.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=\ngoogle.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=\ngoogle.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=\ngoogle.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=\ngoogle.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E=\ngoogle.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=\ngoogle.golang.org/api v0.61.0 h1:TXXKS1slM3b2bZNJwD5DV/Tp6/M2cLzLOLh9PjDhrw8=\ngoogle.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=\ngoogle.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=\ngoogle.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=\ngoogle.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=\ngoogle.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=\ngoogle.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE=\ngoogle.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=\ngoogle.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=\ngoogle.golang.org/api v0.78.0 h1:5ewPyCwP43C3i8B6C2Kb+eVAevbnke2xR8VbcSWjS4I=\ngoogle.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=\ngoogle.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=\ngoogle.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=\ngoogle.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=\ngoogle.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=\ngoogle.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=\ngoogle.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=\ngoogle.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=\ngoogle.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 h1:c7yRRmuQiVMo+YppNj5MUREXUyc2lPo3DrtYMwaWQ28=\ngoogle.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=\ngoogle.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb h1:0m9wktIpOxGw+SSKmydXWB3Z3GTfcPP6+q75HCQa6HI=\ngoogle.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=\ngoogle.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=\ngoogle.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335 h1:2D0OT6tPVdrQTOnVe1VQjfJPTED6EZ7fdJ/f6Db6OsY=\ngoogle.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=\ngoogle.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=\ngoogle.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=\ngoogle.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=\ngoogle.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=\ngoogle.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=\ngoogle.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=\ngoogle.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=\ngoogle.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=\ngoogle.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=\ngoogle.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=\ngoogle.golang.org/grpc v1.46.0 h1:oCjezcn6g6A75TGoKYBPgKmVBLexhYLM6MebdrPApP8=\ngoogle.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=\ngoogle.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=\ngoogle.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=\ngoogle.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=\ngoogle.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/main.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"os\"\n\t\"time\"\n\n\t\"cloud.google.com/go/profiler\"\n\t\"contrib.go.opencensus.io/exporter/jaeger\"\n\t\"contrib.go.opencensus.io/exporter/stackdriver\"\n\t\"github.com/sirupsen/logrus\"\n\t\"go.opencensus.io/plugin/ocgrpc\"\n\t\"go.opencensus.io/stats/view\"\n\t\"go.opencensus.io/trace\"\n\t\"golang.org/x/net/context\"\n\t\"google.golang.org/grpc\"\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/reflection\"\n\t\"google.golang.org/grpc/status\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice/genproto\"\n\thealthpb \"google.golang.org/grpc/health/grpc_health_v1\"\n)\n\nconst (\n\tdefaultPort = \"50051\"\n)\n\nvar log *logrus.Logger\n\nfunc init() {\n\tlog = logrus.New()\n\tlog.Level = logrus.DebugLevel\n\tlog.Formatter = &logrus.JSONFormatter{\n\t\tFieldMap: logrus.FieldMap{\n\t\t\tlogrus.FieldKeyTime:  \"timestamp\",\n\t\t\tlogrus.FieldKeyLevel: \"severity\",\n\t\t\tlogrus.FieldKeyMsg:   \"message\",\n\t\t},\n\t\tTimestampFormat: time.RFC3339Nano,\n\t}\n\tlog.Out = os.Stdout\n}\n\nfunc main() {\n\tif os.Getenv(\"DISABLE_TRACING\") == \"\" {\n\t\tlog.Info(\"Tracing enabled.\")\n\t\tgo initTracing()\n\t} else {\n\t\tlog.Info(\"Tracing disabled.\")\n\t}\n\n\tif os.Getenv(\"DISABLE_PROFILER\") == \"\" {\n\t\tlog.Info(\"Profiling enabled.\")\n\t\tgo initProfiling(\"shippingservice\", \"1.0.0\")\n\t} else {\n\t\tlog.Info(\"Profiling disabled.\")\n\t}\n\n\tport := defaultPort\n\tif value, ok := os.LookupEnv(\"PORT\"); ok {\n\t\tport = value\n\t}\n\tport = fmt.Sprintf(\":%s\", port)\n\n\tlis, err := net.Listen(\"tcp\", port)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to listen: %v\", err)\n\t}\n\n\tvar srv *grpc.Server\n\tif os.Getenv(\"DISABLE_STATS\") == \"\" {\n\t\tlog.Info(\"Stats enabled.\")\n\t\tsrv = grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))\n\t} else {\n\t\tlog.Info(\"Stats disabled.\")\n\t\tsrv = grpc.NewServer()\n\t}\n\tsvc := &server{}\n\tpb.RegisterShippingServiceServer(srv, svc)\n\thealthpb.RegisterHealthServer(srv, svc)\n\tlog.Infof(\"Shipping Service listening on port %s\", port)\n\n\t// Register reflection service on gRPC server.\n\treflection.Register(srv)\n\tif err := srv.Serve(lis); err != nil {\n\t\tlog.Fatalf(\"failed to serve: %v\", err)\n\t}\n}\n\n// server controls RPC service responses.\ntype server struct{}\n\n// Check is for health checking.\nfunc (s *server) Check(ctx context.Context, req *healthpb.HealthCheckRequest) (*healthpb.HealthCheckResponse, error) {\n\treturn &healthpb.HealthCheckResponse{Status: healthpb.HealthCheckResponse_SERVING}, nil\n}\n\nfunc (s *server) Watch(req *healthpb.HealthCheckRequest, ws healthpb.Health_WatchServer) error {\n\treturn status.Errorf(codes.Unimplemented, \"health check via Watch not implemented\")\n}\n\n// GetQuote produces a shipping quote (cost) in USD.\nfunc (s *server) GetQuote(ctx context.Context, in *pb.GetQuoteRequest) (*pb.GetQuoteResponse, error) {\n\tlog.Info(\"[GetQuote] received request\")\n\tdefer log.Info(\"[GetQuote] completed request\")\n\n\t// 1. Generate a quote based on the total number of items to be shipped.\n\tquote := CreateQuoteFromCount(0)\n\n\t// 2. Generate a response.\n\treturn &pb.GetQuoteResponse{\n\t\tCostUsd: &pb.Money{\n\t\t\tCurrencyCode: \"USD\",\n\t\t\tUnits:        int64(quote.Dollars),\n\t\t\tNanos:        int32(quote.Cents * 10000000)},\n\t}, nil\n\n}\n\n// ShipOrder mocks that the requested items will be shipped.\n// It supplies a tracking ID for notional lookup of shipment delivery status.\nfunc (s *server) ShipOrder(ctx context.Context, in *pb.ShipOrderRequest) (*pb.ShipOrderResponse, error) {\n\tlog.Info(\"[ShipOrder] received request\")\n\tdefer log.Info(\"[ShipOrder] completed request\")\n\t// 1. Create a Tracking ID\n\tbaseAddress := fmt.Sprintf(\"%s, %s, %s\", in.Address.StreetAddress, in.Address.City, in.Address.State)\n\tid := CreateTrackingId(baseAddress)\n\n\t// 2. Generate a response.\n\treturn &pb.ShipOrderResponse{\n\t\tTrackingId: id,\n\t}, nil\n}\n\nfunc initJaegerTracing() {\n\tsvcAddr := os.Getenv(\"JAEGER_SERVICE_ADDR\")\n\tif svcAddr == \"\" {\n\t\tlog.Info(\"jaeger initialization disabled.\")\n\t\treturn\n\t}\n\n\t// Register the Jaeger exporter to be able to retrieve\n\t// the collected spans.\n\texporter, err := jaeger.NewExporter(jaeger.Options{\n\t\tEndpoint: fmt.Sprintf(\"http://%s\", svcAddr),\n\t\tProcess: jaeger.Process{\n\t\t\tServiceName: \"shippingservice\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\ttrace.RegisterExporter(exporter)\n\tlog.Info(\"jaeger initialization completed.\")\n}\n\nfunc initStats(exporter *stackdriver.Exporter) {\n\tview.SetReportingPeriod(60 * time.Second)\n\tview.RegisterExporter(exporter)\n\tif err := view.Register(ocgrpc.DefaultServerViews...); err != nil {\n\t\tlog.Warn(\"Error registering default server views\")\n\t} else {\n\t\tlog.Info(\"Registered default server views\")\n\t}\n}\n\nfunc initStackdriverTracing() {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\texporter, err := stackdriver.NewExporter(stackdriver.Options{})\n\t\tif err != nil {\n\t\t\tlog.Warnf(\"failed to initialize Stackdriver exporter: %+v\", err)\n\t\t} else {\n\t\t\ttrace.RegisterExporter(exporter)\n\t\t\ttrace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})\n\t\t\tlog.Info(\"registered Stackdriver tracing\")\n\n\t\t\t// Register the views to collect server stats.\n\t\t\tinitStats(exporter)\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver exporter\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver exporter after retrying, giving up\")\n}\n\nfunc initTracing() {\n\tinitJaegerTracing()\n\tinitStackdriverTracing()\n}\n\nfunc initProfiling(service, version string) {\n\t// TODO(ahmetb) this method is duplicated in other microservices using Go\n\t// since they are not sharing packages.\n\tfor i := 1; i <= 3; i++ {\n\t\tif err := profiler.Start(profiler.Config{\n\t\t\tService:        service,\n\t\t\tServiceVersion: version,\n\t\t\t// ProjectID must be set if not running on GCP.\n\t\t\t// ProjectID: \"my-project\",\n\t\t}); err != nil {\n\t\t\tlog.Warnf(\"failed to start profiler: %+v\", err)\n\t\t} else {\n\t\t\tlog.Info(\"started Stackdriver profiler\")\n\t\t\treturn\n\t\t}\n\t\td := time.Second * 10 * time.Duration(i)\n\t\tlog.Infof(\"sleeping %v to retry initializing Stackdriver profiler\", d)\n\t\ttime.Sleep(d)\n\t}\n\tlog.Warn(\"could not initialize Stackdriver profiler after retrying, giving up\")\n}\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/quote.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\n// Quote represents a currency value.\ntype Quote struct {\n\tDollars uint32\n\tCents   uint32\n}\n\n// String representation of the Quote.\nfunc (q Quote) String() string {\n\treturn fmt.Sprintf(\"$%d.%d\", q.Dollars, q.Cents)\n}\n\n// CreateQuoteFromCount takes a number of items and returns a Price struct.\nfunc CreateQuoteFromCount(count int) Quote {\n\treturn CreateQuoteFromFloat(8.99)\n}\n\n// CreateQuoteFromFloat takes a price represented as a float and creates a Price struct.\nfunc CreateQuoteFromFloat(value float64) Quote {\n\tunits, fraction := math.Modf(value)\n\treturn Quote{\n\t\tuint32(units),\n\t\tuint32(math.Trunc(fraction * 100)),\n\t}\n}"
  },
  {
    "path": "microservices-demo/src/shippingservice/shippingservice_test.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"testing\"\n\n\t\"golang.org/x/net/context\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/shippingservice/genproto\"\n)\n\n// TestGetQuote is a basic check on the GetQuote RPC service.\nfunc TestGetQuote(t *testing.T) {\n\ts := server{}\n\n\t// A basic test case to test logic and protobuf interactions.\n\treq := &pb.GetQuoteRequest{\n\t\tAddress: &pb.Address{\n\t\t\tStreetAddress: \"Muffin Man\",\n\t\t\tCity:          \"London\",\n\t\t\tState:         \"\",\n\t\t\tCountry:       \"England\",\n\t\t},\n\t\tItems: []*pb.CartItem{\n\t\t\t{\n\t\t\t\tProductId: \"23\",\n\t\t\t\tQuantity:  1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tProductId: \"46\",\n\t\t\t\tQuantity:  3,\n\t\t\t},\n\t\t},\n\t}\n\n\tres, err := s.GetQuote(context.Background(), req)\n\tif err != nil {\n\t\tt.Errorf(\"TestGetQuote (%v) failed\", err)\n\t}\n\tif res.CostUsd.GetUnits() != 8 || res.CostUsd.GetNanos() != 990000000 {\n\t\tt.Errorf(\"TestGetQuote: Quote value '%d.%d' does not match expected '%s'\", res.CostUsd.GetUnits(), res.CostUsd.GetNanos(), \"11.220000000\")\n\t}\n}\n\n// TestShipOrder is a basic check on the ShipOrder RPC service.\nfunc TestShipOrder(t *testing.T) {\n\ts := server{}\n\n\t// A basic test case to test logic and protobuf interactions.\n\treq := &pb.ShipOrderRequest{\n\t\tAddress: &pb.Address{\n\t\t\tStreetAddress: \"Muffin Man\",\n\t\t\tCity:          \"London\",\n\t\t\tState:         \"\",\n\t\t\tCountry:       \"England\",\n\t\t},\n\t\tItems: []*pb.CartItem{\n\t\t\t{\n\t\t\t\tProductId: \"23\",\n\t\t\t\tQuantity:  1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tProductId: \"46\",\n\t\t\t\tQuantity:  3,\n\t\t\t},\n\t\t},\n\t}\n\n\tres, err := s.ShipOrder(context.Background(), req)\n\tif err != nil {\n\t\tt.Errorf(\"TestShipOrder (%v) failed\", err)\n\t}\n\t// @todo improve quality of this test to check for a pattern such as '[A-Z]{2}-\\d+-\\d+'.\n\tif len(res.TrackingId) != 18 {\n\t\tt.Errorf(\"TestShipOrder: Tracking ID is malformed - has %d characters, %d expected\", len(res.TrackingId), 18)\n\t}\n}\n"
  },
  {
    "path": "microservices-demo/src/shippingservice/tracker.go",
    "content": "// Copyright 2018 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//      http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\n// seeded determines if the random number generator is ready.\nvar seeded bool = false\n\n// CreateTrackingId generates a tracking ID.\nfunc CreateTrackingId(salt string) string {\n\tif !seeded {\n\t\trand.Seed(time.Now().UnixNano())\n\t\tseeded = true\n\t}\n\n\treturn fmt.Sprintf(\"%c%c-%d%s-%d%s\",\n\t\tgetRandomLetterCode(),\n\t\tgetRandomLetterCode(),\n\t\tlen(salt),\n\t\tgetRandomNumber(3),\n\t\tlen(salt)/2,\n\t\tgetRandomNumber(7),\n\t)\n}\n\n// getRandomLetterCode generates a code point value for a capital letter.\nfunc getRandomLetterCode() uint32 {\n\treturn 65 + uint32(rand.Intn(25))\n}\n\n// getRandomNumber generates a string representation of a number with the requested number of digits.\nfunc getRandomNumber(digits int) string {\n\tstr := \"\"\n\tfor i := 0; i < digits; i++ {\n\t\tstr = fmt.Sprintf(\"%s%d\", str, rand.Intn(10))\n\t}\n\n\treturn str\n}\n"
  },
  {
    "path": "microservices-demo/tilt-resources/dev/tilt_config.json",
    "content": "{\n    \"allowed_contexts\": [\n        \"do-nyc1-microservices-demo-dev\"\n    ],\n    \"default_registry\": \"registry.digitalocean.com/microservices-demo\",\n    \"environment\": \"dev\",\n    \"microservices\": [\n        \"cartservice\",\n        \"checkoutservice\",\n        \"currencyservice\",\n        \"emailservice\",\n        \"frontend\",\n        \"paymentservice\",\n        \"productcatalogservice\",\n        \"recommendationservice\",\n        \"redis\",\n        \"shippingservice\"\n    ],\n    \"namespace\": \"microservices-demo-dev\",\n    \"port_forwards\": [\n        \"frontend:9090\"\n    ]\n}\n"
  },
  {
    "path": "microservices-demo/tilt-resources/local/tilt_config.json",
    "content": "{\n    \"allowed_contexts\": [\n        \"docker-desktop\"\n    ],\n    \"default_registry\": \"\",\n    \"environment\": \"local\",\n    \"microservices\": [\n        \"cartservice\",\n        \"checkoutservice\",\n        \"currencyservice\",\n        \"emailservice\",\n        \"frontend\",\n        \"paymentservice\",\n        \"productcatalogservice\",\n        \"recommendationservice\",\n        \"redis\",\n        \"shippingservice\"\n    ],\n    \"namespace\": \"microservices-demo-local\",\n    \"port_forwards\": [\n        \"frontend:9090\"\n    ]\n}\n"
  },
  {
    "path": "podinfo-example/README.md",
    "content": "# Overview\n\n[Podinfo](https://github.com/stefanprodan/podinfo) is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes. Podinfo is used by CNCF projects like [Flux](https://github.com/fluxcd/flux2) and [Flagger](https://github.com/fluxcd/flagger) for end-to-end testing and workshops.\n\nSpecifications:\n\n- Health checks (readiness and liveness).\n- Graceful shutdown on interrupt signals.\n- File watcher for secrets and configmaps.\n- Instrumented with Prometheus and Open Telemetry.\n- Structured logging with zap.\n- 12-factor app with viper.\n- Fault injection (random errors and latency).\n- Swagger docs.\n- CUE, Helm and Kustomize installers.\n- End-to-End testing with Kubernetes Kind and Helm.\n- Kustomize testing with GitHub Actions and Open Policy Agent.\n- Multi-arch container image with Docker buildx and Github Actions.\n- Container image signing with Sigstore cosign.\n- CVE scanning with Trivy.\n\nPlease visit the [Podinfo](https://github.com/stefanprodan/podinfo) documentation page for more details.\n\n## Requirements\n\nTo complete all steps and deploy the `Podinfo` sample application, you will need:\n\n1. A [DOKS](https://docs.digitalocean.com/products/kubernetes/quickstart) cluster configured and running.\n2. Latest [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) version for Kubernetes interaction.\n3. [Git](https://git-scm.com/downloads) client for interacting with the [kubernetes-sample-apps](https://github.com/digitalocean/kubernetes-sample-apps) repository.\n\n## Deploying to Kubernetes\n\nThe [kustomization manifest](kustomize/kustomization.yaml) provided in this repository will get you started with deploying the `Podinfo` application Kubernetes resources.\n\nFirst, you need to clone this repository:\n\n```shell\ngit clone https://github.com/digitalocean/kubernetes-sample-apps.git\n```\n\nThen, change directory to your local copy:\n\n```shell\ncd kubernetes-sample-apps\n```\n\nNow, create Podinfo sample application Kubernetes resources using the kubectl kustomize option (`-k` flag):\n\n```shell\nkubectl apply -k podinfo-example/kustomize\n```\n\nThe output looks similar to:\n\n```text\nnamespace/podinfo created\nservice/podinfo created\ndeployment.apps/podinfo created\nhorizontalpodautoscaler.autoscaling/podinfo created\n```\n\nIf everything went well, you should have a new Kubernetes namespace created named `podinfo`. Inside the new namespace, you can inspect all resources created by the kustomization manifest from the sample apps repository (all Podinfo application pods should be up and running):\n\n```shell\nkubectl get all -n podinfo\n```\n\nThe output looks similar to:\n\n```text\nNAME                          READY   STATUS    RESTARTS   AGE\npod/podinfo-df7bb55d4-dhrpx   1/1     Running   0          107s\npod/podinfo-df7bb55d4-jhq7m   1/1     Running   0          91s\n\nNAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE\nservice/podinfo   ClusterIP   10.245.152.36   <none>        9898/TCP,9999/TCP   109s\n\nNAME                      READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/podinfo   2/2     2            2           108s\n\nNAME                                DESIRED   CURRENT   READY   AGE\nreplicaset.apps/podinfo-df7bb55d4   2         2         2       109s\n\nNAME                                          REFERENCE            TARGETS         MINPODS   MAXPODS   REPLICAS   AGE\nhorizontalpodautoscaler.autoscaling/podinfo   Deployment/podinfo   <unknown>/99%   2         4         2          109s\n```\n\nFinally, port-forward the `podinfo` service using `kubectl`:\n\n```shell\nkubectl port-forward service/podinfo -n podinfo 9898:9898\n```\n\nOpen a web browser and point to [localhost:9898](http://localhost:9898/). You should see the Podinfo application welcome page:\n\n![Podinfo Welcome Page](assets/images/podinfo-welcome-page.png)\n\n## Cleaning Up\n\nTo clean up all Kubernetes resources created by the Podinfo sample application, below command must be used:\n\n```shell\nkubectl delete ns podinfo\n```\n\n**Note:**\n\nKubectl kustomize subcommand has a delete option that can be used - `kubectl delete -k podinfo-example/kustomize`. But, it won't work well in this case because if the namespace is deleted first then the remaining operations will fail.\n"
  },
  {
    "path": "podinfo-example/kustomize/kustomization.yaml",
    "content": "## Podinfo Sample Application Kustomization\n\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Making sure all resources used in this tutorial are created in a dedicated namespace\n# Also specific annotations are added for later identification\nnamespace: podinfo\ncommonAnnotations:\n  provider: kubernetes-sample-apps\n\n# Podinfo resources (namespace, services, deployments, etc)\nresources:\n  - resources/namespace.yaml\n  - github.com/stefanprodan/podinfo/kustomize\n"
  },
  {
    "path": "podinfo-example/kustomize/resources/namespace.yaml",
    "content": "apiVersion: v1\nkind: Namespace\nmetadata:\n  name: podinfo\n"
  }
]